package com.landinfo.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.Polyline;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.landinfo.config.ApplicationProperties;
import com.landinfo.config.GeometryUtil;
import com.landinfo.domain.DynamicTemplate;
import com.landinfo.domain.DynamicTemplateTotal;
import com.landinfo.domain.FieldColumn;
import com.landinfo.repository.DynamicTemplateRepository;
import com.landinfo.service.DynamicTemplateService;
import com.landinfo.service.ImageHelper;
import com.landinfo.web.rest.vm.DynamicTemplateHistoryVM;
import com.landinfo.web.rest.vm.DynamicTemplateTotalVM;
import com.vividsolutions.jts.geom.*;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.geojson.GeoJsonObject;
import org.hibernate.collection.internal.PersistentSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.wololo.jts2geojson.GeoJSONReader;

import javax.servlet.http.HttpServletRequest;
import javax.swing.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 动态模板（动态表单、动态表）
 */
@Service
public class DynamicTemplateServiceImpl implements DynamicTemplateService {

    private final Logger log = LoggerFactory.getLogger(DynamicTemplateService.class);
    /**
     * 动态模板类名
     */
    private final String DynamicTemplateClassName = "DynamicTemplate";
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd");

    private java.text.SimpleDateFormat dateTimeFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private java.text.SimpleDateFormat dateTimeFormatStart = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:00");
    private java.text.SimpleDateFormat dateTimeFormatTodayStart = new java.text.SimpleDateFormat("yyyy-MM-dd 00:00:00");
    private java.text.SimpleDateFormat dateTimeFormatTodayEnd = new java.text.SimpleDateFormat("yyyy-MM-dd 23:59:59");
    private java.text.SimpleDateFormat dateTimeFormatEnd = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:59");


    @Autowired
    private DynamicTemplateRepository dynamicTemplateRepository;

    @Autowired
    private Export2ExcelServiceImpl export2ExcelServiceImpl;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ApplicationProperties applicationProperties;

    @Autowired
    private GeometryUtil geometryUtil;

    public DynamicTemplateServiceImpl() {

    }

    /**
     * 获取最近一分钟或一天的监测数据
     *
     * @return
     */
    @Override
    public HashMap<String, Object> getOneMinutesMonitorData(boolean today) {
        HashMap<String, Object> result = new HashMap<>();

        String hql = String.format("from DynamicTemplate where type='%s'", "monitor");
        List<Object> dynamicTables = this.dynamicTemplateRepository.createQueryList(hql);
        if (dynamicTables != null && dynamicTables.size() > 0) {
            for (int i = 0; i < dynamicTables.size(); i++) {
                String entityName = ((HashMap) dynamicTables.get(i)).get("name").toString();
                long time = 1 * 60 * 1000;//1分钟
                java.util.Date currentDateTime = new java.util.Date();
                Date beforeDate = new Date(currentDateTime.getTime() - time);//30分钟前的时间

                String sql = String.format("from %s t WHERE t.createDateTime between '%s' and '%s' ORDER BY t.createDateTime desc", entityName, dateTimeFormat.format(beforeDate), dateTimeFormatEnd.format(currentDateTime));
                if (today == true) {
                    sql = String.format("from %s t WHERE t.createDateTime between '%s' and '%s' ORDER BY t.createDateTime desc", entityName, dateTimeFormatTodayStart.format(beforeDate), dateTimeFormatEnd.format(currentDateTime));
                }
                List list = null;
                try {
                    list = this.dynamicTemplateRepository.createQueryList(sql);
                } catch (Exception ex) {
                    ex.getLocalizedMessage();
                }
                if (list != null && list.size() > 0) {
                    result.put(entityName, list);
                }
            }
        }
        return result;
    }

    /**
     * 根据name获取dynamicTable数据
     *
     * @param name
     * @return
     */
    @Override
    public Object getDynamicTemplateByName(String name) {
        String hql = String.format("from DynamicTemplate where name='%s'", name);
        return this.dynamicTemplateRepository.createQueryObject(hql); //.createQueryList(hql);
    }

    @Override
    @CacheEvict(value = {"DefaultDynamicTemplateCache", "DefaultDynamicTemplateCache2", "DefaultDynamicTemplate_getAllRecords"}, allEntries = true)
    public boolean deleteById(String tableName, String id) {
        return this.dynamicTemplateRepository.deleteById(tableName, id);
    }

    @Override
    public String getMultChildTableDynamicTable(String type, String parentId, Boolean loadChildData, Boolean loadDomain) {
        List<Object> resultList = new ArrayList<>();
        String hql = String.format("from DynamicTemplate where type='%s' order by sorting", type);
        List<Object> dynamicTable = this.dynamicTemplateRepository.createQueryList(hql); //session.createQuery(hql).list();
        if (dynamicTable != null) {
            for (int i = 0; i < dynamicTable.size(); i++) {
                HashMap hashMapObject = (HashMap) dynamicTable.get(i);
                JSONObject resultTempObject = null;
                if (hashMapObject != null) {
                    if (hashMapObject.containsKey("childrenXml")) {
                        hashMapObject.remove("childrenXml");
                    }
                    String tempContent = hashMapObject.get("jsonContent").toString();
                    if (tempContent != null && !"".equals(tempContent)) {
                        resultTempObject = (JSONObject) JSON.parse(tempContent);
                        resultTempObject.put("tableName", hashMapObject.get("name"));
                        if (loadDomain == false) {
                            if (resultTempObject.containsKey("fieldColumnsDomain")) {
                                resultTempObject.remove("fieldColumnsDomain");
                            }
                        }
                    }
                    String tableName = hashMapObject.get("name").toString();
                    hql = String.format("from %s where pguid='%s'", tableName, parentId);

                    List<Object> tempObject = this.dynamicTemplateRepository.createQueryListTopN(hql, 100);
                    if (tempObject != null && tempObject.size() > 0) {
                        HashMap hashMapObject2 = (HashMap) tempObject.get(0);
                        String id = hashMapObject2.get("id").toString();
                        resultTempObject.put("id", id);
                        if (hashMapObject2.containsKey("geom")) {
                            resultTempObject.put("mainTable", true);
                            if (hashMapObject2.get("geom") != null) {
                                hashMapObject2.replace("geom", hashMapObject2.get("geom").toString());
                            }
//                            if (tempObject.size() >= 2) {
//                                for (int j = 1; j < tempObject.size(); j++) {
//                                    hashMapObject2 = (HashMap) tempObject.get(j);
//                                    if (hashMapObject2.get("geom") != null) {
//                                        hashMapObject2.replace("geom", hashMapObject2.get("geom").toString());
//                                    }
//                                }
//                                resultTempObject.put("rows", tempObject);
//                            } else {
//                                resultTempObject.put("rows", hashMapObject2);
//                            }
                            resultTempObject = replaceGeom(tempObject, hashMapObject2, resultTempObject);
                        } else {
                            resultTempObject.put("mainTable", false);
                            if (loadChildData == true) {
//                                if (tempObject.size() >= 2) {
//                                    for (int j = 1; j < tempObject.size(); j++) {
//                                        hashMapObject2 = (HashMap) tempObject.get(j);
//                                        if (hashMapObject2.get("geom") != null) {
//                                            hashMapObject2.replace("geom", hashMapObject2.get("geom").toString());
//                                        }
//                                    }
//                                    resultTempObject.put("rows", tempObject);
//                                } else {
//                                    resultTempObject.put("rows", hashMapObject2);
//                                }
                                resultTempObject = replaceGeom(tempObject, hashMapObject2, resultTempObject);
                            }
                        }
                    }
                }
                resultList.add(resultTempObject);
            }
        }
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        String result = gson.toJson(resultList);
        return result;
    }


    private JSONObject replaceGeom(List<Object> tempObject, HashMap hashMapObject2, JSONObject resultTempObject) {
        if (tempObject.size() >= 2) {
            for (int j = 1; j < tempObject.size(); j++) {
                hashMapObject2 = (HashMap) tempObject.get(j);
                if (hashMapObject2.get("geom") != null) {
                    hashMapObject2.replace("geom", hashMapObject2.get("geom").toString());
                }
            }
            resultTempObject.put("rows", tempObject);
        } else {
            resultTempObject.put("rows", tempObject);
        }
        return resultTempObject;
    }

    /**
     * 根据模板类型指定parentId删除动态表数据（针对非级联关联）
     *
     * @param templateType
     * @param parentId
     * @return
     */
    @Override
    @CacheEvict(value = {"DefaultDynamicTemplateCache", "DefaultDynamicTemplateCache2", "DefaultDynamicTemplate_getAllRecords"}, allEntries = true)
    public Boolean deleteByParentId(String templateType, String parentId) {
        String parentIdFieldName = this.applicationProperties.getGrassAuthenticRightParentIdFieldName();
        if (parentIdFieldName == null) {
            parentIdFieldName = "pguid";
        }
        String hql = String.format("select name from DynamicTemplate where type='%s' order by sorting desc", templateType);
        List dynamicTable = this.dynamicTemplateRepository.createQueryList(hql); //session.createQuery(hql).list();
        Boolean result = true;
        if (dynamicTable != null) {
            for (int i = 0; i < dynamicTable.size(); i++) {
                String tableName = (String) dynamicTable.get(i);
                hql = String.format("from %s where %s='%s'", tableName, parentIdFieldName, parentId);
                List list = this.dynamicTemplateRepository.createQueryList(hql);
                if (list != null && list.size() > 0) {
                    for (int j = 0; j < list.size(); j++) {
                        Boolean isOk = this.dynamicTemplateRepository.delete(list.get(j));
                        if (!isOk) {
                            result = false;
                        }
                    }
                }

            }
        }
        return result;
    }

    @Override
    public String getFieldUniqueValue(String entityName, String fieldName) {
        String[] fields = fieldName.split(",");
        HashMap<String, Object> hashMap = new HashMap<>();
        for (int i = 0; i < fields.length; i++) {
            if (!hashMap.containsKey(fields[i])) {
                try {
                    String hql = String.format("select distinct %s from %s ", fields[i], entityName);
                    List dynamicTable = this.dynamicTemplateRepository.createQueryList(hql);
                    hashMap.put(fields[i], dynamicTable);
                } catch (Exception ex) {

                }
            }
        }
        return JSON.toJSONString(hashMap);
    }


    /**
     * 统计分析
     *
     * @param dynamicTemplateTotalVM
     * @return
     */
    @Override
    public String getTotalTemplate(DynamicTemplateTotalVM dynamicTemplateTotalVM) {
        if (dynamicTemplateTotalVM == null) {
            return "error:输入参数为空";
        }
        try {
            HashMap<String, DynamicTemplateTotal> results = new HashMap<>();
            if(dynamicTemplateTotalVM.getType() != null && !"".equals(dynamicTemplateTotalVM.getType()) && "customize".equals(dynamicTemplateTotalVM.getType())){
                // 自定义分析
                results = getTotalTemplateForCustomize(dynamicTemplateTotalVM);
            }else if(dynamicTemplateTotalVM.getDataSource() != null && !"".equals(dynamicTemplateTotalVM.getDataSource()) && "simpleLine".equals(dynamicTemplateTotalVM.getDataSource())){
                // 按样线分析统计
                results = this.getTotalTemplateForSimpleLine(dynamicTemplateTotalVM);
            }else {
                // 按模板和人员分析
                String hql = String.format("from DynamicTemplate where type='%s'", dynamicTemplateTotalVM.getDataSource());
                List<Object> dynamicTables = this.dynamicTemplateRepository.createQueryList(hql);
                if (dynamicTables != null && dynamicTables.size() > 0) {
                    for (int i = 0; i < dynamicTables.size(); i++) {
                        HashMap dynamicTable = (HashMap) dynamicTables.get(i);
                        String tableName = dynamicTable.get("name").toString();
                        String jsonContent = dynamicTable.get("jsonContent").toString();
                        JSONObject jsonObject = JSON.parseObject(jsonContent);
                        String xFieldName = null;
                        String yFieldName = null;
                        String zFieldName = null;
                        // 通过巡护点位获取海拔区间
                        String locationZIntervalSql = null;
                        String tableNameCn = "";
                        String patrolMileageFieldName = "";
                        boolean isSimpleLineTable = false;
                        if (jsonObject != null) {
                            tableNameCn = jsonObject.get("name").toString();
                            JSONArray jsonArrayFieldColumns = (JSONArray) jsonObject.get("fieldColumns");
                            if (jsonArrayFieldColumns != null) {
                                for (int k = 0; k < jsonArrayFieldColumns.size(); k++) {
                                    String frontType = ((JSONObject) jsonArrayFieldColumns.get(k)).get("frontType").toString().toUpperCase();
                                    if ("patrol".equals(dynamicTemplateTotalVM.getDataSource())) {
                                        if ("recordGpsLocation".toUpperCase().equals(frontType)) {
                                            patrolMileageFieldName = ((JSONObject) jsonArrayFieldColumns.get(k)).get("fieldName") + "Length";
                                        }
                                    }else {
                                        if ("locationX".toUpperCase().equals(frontType) || "locationXNoEdit".toUpperCase().equals(frontType)) {
                                            xFieldName = ((JSONObject) jsonArrayFieldColumns.get(k)).get("fieldName").toString();
                                        }
                                        if ("locationY".toUpperCase().equals(frontType) || "locationYNoEdit".toUpperCase().equals(frontType)) {
                                            yFieldName = ((JSONObject) jsonArrayFieldColumns.get(k)).get("fieldName").toString();
                                        }
                                        if ("locationZ".toUpperCase().equals(frontType) || "locationZNoEdit".toUpperCase().equals(frontType)) {
                                            zFieldName = ((JSONObject) jsonArrayFieldColumns.get(k)).get("fieldName").toString();
                                        }
                                    }
                                    if ("simpleLine".toUpperCase().equals(frontType)) {
                                        isSimpleLineTable = true;
                                        break;
                                    }
                                }
                            }
                        }
                        // 若为样线监测模板，则直接跳过
                        if(isSimpleLineTable){
                            continue;
                        }
                        String where = String.format("1=1 ");
                        String whereForLocationZ = String.format("1=1 ");
                        if (dynamicTemplateTotalVM != null && dynamicTemplateTotalVM.getStartDateTime() != null) {
                            where += String.format(" and createDateTime>='%s'", dateTimeFormatTodayStart.format(dynamicTemplateTotalVM.getStartDateTime()));
                            whereForLocationZ += String.format(" and createDateTime>='%s'", dateTimeFormatTodayStart.format(dynamicTemplateTotalVM.getStartDateTime()));
                        }
                        if (dynamicTemplateTotalVM != null && dynamicTemplateTotalVM.getStartDateTime() != null) {
                            where += String.format(" and createDateTime<='%s'", dateTimeFormatTodayEnd.format(dynamicTemplateTotalVM.getEndDateTime()));
                            whereForLocationZ += String.format(" and createDateTime<='%s'", dateTimeFormatTodayEnd.format(dynamicTemplateTotalVM.getEndDateTime()));
                        }
                        boolean userType = (dynamicTemplateTotalVM != null && (dynamicTemplateTotalVM.getType() == null || "".equals(dynamicTemplateTotalVM.getType()) || "user".equals(dynamicTemplateTotalVM.getType())));
                        String tableType = dynamicTable.get("type").toString();
                        //按用户分析
                        if (userType) {
                            if (!"patrol".equals(dynamicTemplateTotalVM.getDataSource())) {
                                // 判断是否需要获取海拔区间
                                if(zFieldName != null){
                                    hql = String.format("select a.createAuthor,count(a),min(a.%s) as minZ,max(a.%s) as maxZ from %s a where %s GROUP BY a.createAuthor",
                                        zFieldName, zFieldName, tableName, where);
                                }else {
                                    hql = String.format("select a.createAuthor,count(a) from %s a where %s GROUP BY a.createAuthor", tableName, where);
                                }
                            } else {
                                where += String.format(" and a.结束时间 > a.开始时间 and date_part('day', (a.结束时间 - a.开始时间)) < %s", dynamicTemplateTotalVM.getCannotBeyondDay());
                                hql = String.format("select a.createAuthor,count(a),ABS(sum(date_part('day', (a.结束时间 - a.开始时间))*24 + date_part('hour', (a.结束时间 - a.开始时间)))) from %s a where %s GROUP BY a.createAuthor", tableName, where);
                                if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName)) {
                                    hql = String.format("select a.createAuthor,count(a),ABS(sum(date_part('day', (a.结束时间 - a.开始时间))*24 + date_part('hour', (a.结束时间 - a.开始时间)))),sum(a.%s) from %s a where %s GROUP BY a.createAuthor",
                                        patrolMileageFieldName, tableName, where);
                                }
                                // 获取海拔区间sql
                                whereForLocationZ += String.format(" and dynamicTableName = '%s'", tableName);
                                locationZIntervalSql = String.format("select author,min(g.z) as minZ,max(g.z) as maxZ from GpsLocation g where %s GROUP BY g.author", whereForLocationZ);
                            }
                        } else {
                            if (!"patrol".equals(dynamicTemplateTotalVM.getDataSource())) {
                                if(zFieldName != null){
                                    hql = String.format("select count(a),min(a.%s) as minZ,max(a.%s) as maxZ from %s a where %s ", zFieldName, zFieldName, tableName, where);
                                }else {
                                    hql = String.format("select count(a) from %s a where %s ", tableName, where);
                                }
                            } else {
                                where += String.format(" and a.结束时间 > a.开始时间 and date_part('day', (a.结束时间 - a.开始时间)) < %s", dynamicTemplateTotalVM.getCannotBeyondDay());
                                hql = String.format("select count(a),ABS(sum(date_part('day', (a.结束时间 - a.开始时间))*24 + date_part('hour', (a.结束时间 - a.开始时间)))) from %s a where %s ", tableName, where);
                                if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName)) {
                                    hql = String.format("select count(a),ABS(sum(date_part('day', (a.结束时间 - a.开始时间))*24 + date_part('hour', (a.结束时间 - a.开始时间)))),sum(a.%s) from %s a where %s ",
                                        patrolMileageFieldName, tableName, where);
                                }
                                // 获取海拔区间sql
                                whereForLocationZ += String.format(" and dynamicTableName = '%s'", tableName);
                                locationZIntervalSql = String.format("select dynamicTableName,min(g.z) as minZ,max(g.z) as maxZ from GpsLocation g where %s GROUP BY g.dynamicTableName", whereForLocationZ);
                            }
                        }
                        // 执行查询统计
                        List<Object> users = this.dynamicTemplateRepository.createQueryList(hql);  // session.createQuery(hql).getResultList();
                        if (users != null) {
                            // 若为巡护模板，则需额外查询gps点位表获取海拔区间
                            List<Object> locationZIntervals = new ArrayList<>();
                            if(locationZIntervalSql != null){
                                locationZIntervals = this.dynamicTemplateRepository.createQueryList(locationZIntervalSql);
                            }
                            // 遍历查询结果赋值
                            for (int j = 0; j < users.size(); j++) {
                                Object[] item = null;
                                if (users.get(j) instanceof Object[]) {
                                    item = ((Object[]) users.get(j));
                                } else {
                                    item = new Object[2];
                                    item[0] = users.get(j);
                                    item[1] = tableName;
                                }
                                String altitudeInterval = null;
                                String tempName = item[0] + tableName;
                                if (!"user".equals(dynamicTemplateTotalVM.getType())) {
                                    tempName = tableName;
                                    // 设置海拔区间
                                    if(locationZIntervals != null && locationZIntervals.size() > 0){
                                        // 巡护模板
                                        for (int l = 0; l < locationZIntervals.size(); l++) {
                                            Object[] values = null;
                                            if (locationZIntervals.get(l) instanceof Object[]) {
                                                values = ((Object[]) locationZIntervals.get(l));
                                                if(values.length >= 3 && values[0] != null && values[1] != null && values[2] != null
                                                    && values[0].toString().equals(tableName)){
                                                    altitudeInterval = Math.round((double)values[1]) +"—"+ Math.round((double)values[2]);
                                                    break;
                                                }
                                            }
                                        }
                                    }else if(locationZIntervalSql == null && item.length == 3 && item[1] != null && item[2] != null){
                                        // 监测、专项模板
                                        altitudeInterval = Math.round((double)item[1]) +"—"+ Math.round((double)item[2]);
                                    }
                                }else {
                                    // 设置海拔区间
                                    if(locationZIntervals != null && locationZIntervals.size() > 0){
                                        for (int l = 0; l < locationZIntervals.size(); l++) {
                                            Object[] values = null;
                                            if (locationZIntervals.get(l) instanceof Object[]) {
                                                values = ((Object[]) locationZIntervals.get(l));
                                                if(values.length >= 3 && values[0] != null && item[0] != null && values[1] != null && values[2] != null
                                                    && values[0].toString().equals(item[0].toString())){
                                                    altitudeInterval = Math.round((double)values[1]) +"—"+ Math.round((double)values[2]);
                                                    break;
                                                }
                                            }
                                        }
                                    }else if(locationZIntervalSql == null && item.length == 4 && item[2] != null && item[3] != null){
                                        // 监测、专项模板
                                        altitudeInterval = Math.round((double)item[2]) +"—"+ Math.round((double)item[3]);
                                    }
                                }
                                if (!results.containsKey(tempName)) {
                                    DynamicTemplateTotal dynamicTemplateTotal = new DynamicTemplateTotal();
                                    dynamicTemplateTotal.setName(item[0] + "");
                                    dynamicTemplateTotal.setNameCn(tableNameCn);
                                    dynamicTemplateTotal.setType(tableType);
                                    if (userType) {
                                        dynamicTemplateTotal.setCount(Integer.parseInt("0" + item[1]));
                                        if ("patrol".equals(dynamicTemplateTotalVM.getDataSource()) && item.length >= 3 && item[2] != null) {
                                            dynamicTemplateTotal.setTime(Integer.parseInt("0" + item[2]));
                                        }
                                        if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName) && item.length >= 4 && item[3] != null) {
                                            dynamicTemplateTotal.setPatrolMileage(Double.parseDouble("0" + item[3]));
                                        }
                                    } else {
                                        dynamicTemplateTotal.setCount(Integer.parseInt("0" + item[0]));
                                        if ("patrol".equals(dynamicTemplateTotalVM.getDataSource()) && item.length >= 2 && item[1] != null && (item[1] instanceof Long || item[1] instanceof Integer)) {
                                            dynamicTemplateTotal.setTime(Integer.parseInt("0" + item[1]));
                                        }
                                        if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName) && item.length >= 3 && item[2] != null) {
                                            dynamicTemplateTotal.setPatrolMileage(Double.parseDouble("0" + item[2]));
                                        }
                                    }
                                    if(altitudeInterval != null){
                                        dynamicTemplateTotal.setAltitudeInterval(altitudeInterval);
                                    }
                                    if (xFieldName != null && yFieldName != null) {
                                        hql = String.format("select %s,%s,createAuthor,createDateTime from %s where %s and %s !=null and %s !=null", xFieldName, yFieldName, tableName, where, xFieldName, yFieldName);
                                        List<Object> xyLocation = this.dynamicTemplateRepository.createQueryList(hql);   // session.createQuery(hql).getResultList();
                                        if (xyLocation != null && xyLocation.size() > 0) {
                                            dynamicTemplateTotal.setPoints(xyLocation);
                                        }
                                    }
                                    results.put(tempName, dynamicTemplateTotal);
                                } else {
                                    DynamicTemplateTotal tempDynamicTemplateTotal = results.get(tempName);
                                    if (tempDynamicTemplateTotal != null) {
                                        tempDynamicTemplateTotal.setType(tableType);
                                        tempDynamicTemplateTotal.setNameCn(tableNameCn);
                                        if (userType) {
                                            tempDynamicTemplateTotal.setCount(tempDynamicTemplateTotal.getCount() + Integer.parseInt("0" + item[1]));
                                            if ("patrol".equals(dynamicTemplateTotalVM.getDataSource()) && item.length >= 3 && item[2] != null) {
                                                tempDynamicTemplateTotal.setTime(tempDynamicTemplateTotal.getTime() + Integer.parseInt("0" + item[2]));
                                            }
                                            if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName) && item.length >= 4 && item[3] != null) {
                                                tempDynamicTemplateTotal.setPatrolMileage(tempDynamicTemplateTotal.getPatrolMileage() + Double.parseDouble("0" + item[3]));
                                            }
                                        } else {
                                            tempDynamicTemplateTotal.setCount(tempDynamicTemplateTotal.getCount() + Integer.parseInt("0" + item[0]));
                                            if ("patrol".equals(dynamicTemplateTotalVM.getDataSource()) && item.length >= 2 && item[1] != null) {
                                                tempDynamicTemplateTotal.setTime(tempDynamicTemplateTotal.getTime() + Integer.parseInt("0" + item[1]));
                                            }
                                            if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName) && item.length >= 3 && item[2] != null) {
                                                tempDynamicTemplateTotal.setPatrolMileage(tempDynamicTemplateTotal.getPatrolMileage() + Double.parseDouble("0" + item[2]));
                                            }
                                        }
                                        if(altitudeInterval != null){
                                            tempDynamicTemplateTotal.setAltitudeInterval(altitudeInterval);
                                        }
                                        results.replace(tempName, tempDynamicTemplateTotal);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //session.close();
            return JSON.toJSONStringWithDateFormat(results, "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
        } catch (Exception ex) {
            //session.close();
            log.error(ex.getLocalizedMessage());
            return null;
        }
    }
    // 按样线分析统计
    private HashMap<String, DynamicTemplateTotal> getTotalTemplateForSimpleLine(DynamicTemplateTotalVM dynamicTemplateTotalVM){
        HashMap<String, DynamicTemplateTotal> results = new HashMap<>();
        // 按模板和人员分析样线
        String hql = " from DynamicTemplate where type='patrol'";
        List<Object> dynamicTables = this.dynamicTemplateRepository.createQueryList(hql);
        if (dynamicTables != null && dynamicTables.size() > 0) {
            for (int i = 0; i < dynamicTables.size(); i++) {
                HashMap dynamicTable = (HashMap) dynamicTables.get(i);
                String tableName = dynamicTable.get("name").toString();
                String jsonContent = dynamicTable.get("jsonContent").toString();
                JSONObject jsonObject = JSON.parseObject(jsonContent);
                String zFieldName = null;
                String simpleLineFieldName = "监测样线";
                // 通过巡护点位获取海拔区间
                String locationZIntervalSql = null;
                String tableNameCn = "";
                String patrolMileageFieldName = "";
                boolean isSimpleLineTable = false;
                if (jsonObject != null) {
                    tableNameCn = jsonObject.get("name").toString();
                    JSONArray jsonArrayFieldColumns = (JSONArray) jsonObject.get("fieldColumns");
                    if (jsonArrayFieldColumns != null) {
                        for (int k = 0; k < jsonArrayFieldColumns.size(); k++) {
                            String frontType = ((JSONObject) jsonArrayFieldColumns.get(k)).get("frontType").toString().toUpperCase();
                            if ("patrol".equals(dynamicTemplateTotalVM.getDataSource()) || "simpleLine".equals(dynamicTemplateTotalVM.getDataSource())) {
                                if ("recordGpsLocation".toUpperCase().equals(frontType)) {
                                    patrolMileageFieldName = ((JSONObject) jsonArrayFieldColumns.get(k)).get("fieldName") + "Length";
                                }
                            }else {
                                if ("locationZ".toUpperCase().equals(frontType) || "locationZNoEdit".toUpperCase().equals(frontType)) {
                                    zFieldName = ((JSONObject) jsonArrayFieldColumns.get(k)).get("fieldName").toString();
                                }
                            }
                            if ("simpleLine".toUpperCase().equals(frontType)) {
                                isSimpleLineTable = true;
                                simpleLineFieldName = ((JSONObject) jsonArrayFieldColumns.get(k)).get("fieldName").toString();
                            }
                        }
                    }
                }
                // 若不为样线监测模板，则直接跳过
                if(!isSimpleLineTable){
                    continue;
                }
                String where = String.format("1=1 ");
                String whereForLocationZ = String.format("1=1 ");
                if (dynamicTemplateTotalVM != null && dynamicTemplateTotalVM.getStartDateTime() != null) {
                    where += String.format(" and createDateTime>='%s'", dateTimeFormatTodayStart.format(dynamicTemplateTotalVM.getStartDateTime()));
                    whereForLocationZ += String.format(" and createDateTime>='%s'", dateTimeFormatTodayStart.format(dynamicTemplateTotalVM.getStartDateTime()));
                }
                if (dynamicTemplateTotalVM != null && dynamicTemplateTotalVM.getStartDateTime() != null) {
                    where += String.format(" and createDateTime<='%s'", dateTimeFormatTodayEnd.format(dynamicTemplateTotalVM.getEndDateTime()));
                    whereForLocationZ += String.format(" and createDateTime<='%s'", dateTimeFormatTodayEnd.format(dynamicTemplateTotalVM.getEndDateTime()));
                }
                // 判断查询单个样线还是查询所有样线
                if(dynamicTemplateTotalVM != null && dynamicTemplateTotalVM.getSimpleLineId() != null && !"all".equals(dynamicTemplateTotalVM.getSimpleLineId())){
                    Long simpleLineId = Long.parseLong(dynamicTemplateTotalVM.getSimpleLineId());
                    where += String.format(" and %s='%s'", simpleLineFieldName, simpleLineId);
                }
                boolean userType = (dynamicTemplateTotalVM != null && (dynamicTemplateTotalVM.getType() == null || "".equals(dynamicTemplateTotalVM.getType()) || "user".equals(dynamicTemplateTotalVM.getType())));
                String tableType = dynamicTable.get("type").toString();
                //按用户分析
                if (userType) {
                    if (!"patrol".equals(dynamicTemplateTotalVM.getDataSource()) && !"simpleLine".equals(dynamicTemplateTotalVM.getDataSource())) {
                        // 判断是否需要获取海拔区间
                        if(zFieldName != null){
                            hql = String.format("select a.%s,a.createAuthor,count(a),min(a.%s) as minZ,max(a.%s) as maxZ from %s a where %s GROUP BY a.%s,a.createAuthor",
                                simpleLineFieldName, zFieldName, zFieldName, tableName, where, simpleLineFieldName);
                        }else {
                            hql = String.format("select a.%s,a.createAuthor,count(a) from %s a where %s GROUP BY a.%s,a.createAuthor",
                                simpleLineFieldName, tableName, where, simpleLineFieldName);
                        }
                    } else {
                        where += String.format(" and a.结束时间 > a.开始时间 and date_part('day', (a.结束时间 - a.开始时间)) < %s", dynamicTemplateTotalVM.getCannotBeyondDay());
                        hql = String.format("select a.%s,a.createAuthor,count(a),ABS(sum(date_part('day', (a.结束时间 - a.开始时间))*24 + date_part('hour', (a.结束时间 - a.开始时间)))) from %s a where %s GROUP BY a.%s,a.createAuthor",
                            simpleLineFieldName, tableName, where, simpleLineFieldName);
                        if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName)) {
                            hql = String.format("select a.%s,a.createAuthor,count(a),ABS(sum(date_part('day', (a.结束时间 - a.开始时间))*24 + date_part('hour', (a.结束时间 - a.开始时间)))),sum(a.%s) from %s a where %s GROUP BY a.%s,a.createAuthor",
                                simpleLineFieldName, patrolMileageFieldName, tableName, where, simpleLineFieldName);
                        }
                        // 获取海拔区间sql
                        whereForLocationZ += String.format(" and dynamicTableName = '%s'", tableName);
                        locationZIntervalSql = String.format("select jianceyangxian,author,min(g.z) as minZ,max(g.z) as maxZ from GpsLocation g where %s GROUP BY g.jianceyangxian,g.author", whereForLocationZ);
                    }
                } else {
                    if (!"patrol".equals(dynamicTemplateTotalVM.getDataSource()) && !"simpleLine".equals(dynamicTemplateTotalVM.getDataSource())) {
                        if(zFieldName != null){
                            hql = String.format("select a.%s,count(a),min(a.%s) as minZ,max(a.%s) as maxZ from %s a where %s GROUP BY a.%s",
                                simpleLineFieldName, zFieldName, zFieldName, tableName, where, simpleLineFieldName);
                        }else {
                            hql = String.format("select a.%s,count(a) from %s a where %s GROUP BY a.%s",
                                simpleLineFieldName, tableName, where, simpleLineFieldName);
                        }
                    } else {
                        where += String.format(" and a.结束时间 > a.开始时间 and date_part('day', (a.结束时间 - a.开始时间)) < %s", dynamicTemplateTotalVM.getCannotBeyondDay());
                        hql = String.format("select a.%s,count(a),ABS(sum(date_part('day', (a.结束时间 - a.开始时间))*24 + date_part('hour', (a.结束时间 - a.开始时间)))) from %s a where %s GROUP BY a.%s",
                            simpleLineFieldName, tableName, where, simpleLineFieldName);
                        if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName)) {
                            hql = String.format("select a.%s,count(a),ABS(sum(date_part('day', (a.结束时间 - a.开始时间))*24 + date_part('hour', (a.结束时间 - a.开始时间)))),sum(a.%s) from %s a where %s GROUP BY a.%s",
                                simpleLineFieldName, patrolMileageFieldName, tableName, where, simpleLineFieldName);
                        }
                        // 获取海拔区间sql
                        whereForLocationZ += String.format(" and dynamicTableName = '%s'", tableName);
                        locationZIntervalSql = String.format("select jianceyangxian,dynamicTableName,min(g.z) as minZ,max(g.z) as maxZ from GpsLocation g where %s GROUP BY g.jianceyangxian,g.dynamicTableName", whereForLocationZ);
                    }
                }

                List<Object> users = this.dynamicTemplateRepository.createQueryList(hql);  // session.createQuery(hql).getResultList();
                if (users != null) {
                    // 若为巡护模板，则需额外查询gps点位表获取海拔区间
                    List<Object> locationZIntervals = new ArrayList<>();
                    if(locationZIntervalSql != null){
                        locationZIntervals = this.dynamicTemplateRepository.createQueryList(locationZIntervalSql);
                    }
                    // 遍历查询结果赋值
                    for (int j = 0; j < users.size(); j++) {
                        Object[] item = null;
                        if (users.get(j) instanceof Object[]) {
                            item = ((Object[]) users.get(j));
                        } else {
                            item = new Object[2];
                            item[0] = users.get(j);
                            item[1] = tableName;
                        }
                        if(item[0] == null){
                            continue;
                        }
                        String altitudeInterval = null;
                        String tempName = item[0] + tableName;
                        if (!"user".equals(dynamicTemplateTotalVM.getType())) {
                            // 设置海拔区间
                            if(locationZIntervals != null && locationZIntervals.size() > 0){
                                // 巡护模板
                                for (int l = 0; l < locationZIntervals.size(); l++) {
                                    Object[] values = null;
                                    if (locationZIntervals.get(l) instanceof Object[]) {
                                        values = ((Object[]) locationZIntervals.get(l));
                                        if(values.length >= 4 && values[0] != null && values[1] != null && item[0] != null &&
                                            values[0].toString().equals(item[0].toString()) && values[1].toString().equals(tableName)){
                                            altitudeInterval = Math.round((double)values[2]) +"—"+ Math.round((double)values[3]);
                                            break;
                                        }
                                    }
                                }
                            }else if(locationZIntervalSql == null && item.length == 4 && item[2] != null && item[3] != null){
                                // 监测、专项模板
                                altitudeInterval = Math.round((double)item[2]) +"—"+ Math.round((double)item[3]);
                            }
                        }else {
                            // 设置海拔区间
                            if(locationZIntervals != null && locationZIntervals.size() > 0){
                                for (int l = 0; l < locationZIntervals.size(); l++) {
                                    Object[] values = null;
                                    if (locationZIntervals.get(l) instanceof Object[]) {
                                        values = ((Object[]) locationZIntervals.get(l));
                                        if(values.length >= 4 && item.length >= 2 && values[0] != null && values[1] != null
                                            && item[0] != null && item[1] != null && values[0].toString().equals(item[0].toString())
                                            && values[1].toString().equals(item[1].toString())){
                                            altitudeInterval = Math.round((double)values[2]) +"—"+ Math.round((double)values[3]);
                                            break;
                                        }
                                    }
                                }
                            }else if(locationZIntervalSql == null && item.length == 5 && item[3] != null && item[4] != null){
                                // 监测、专项模板
                                altitudeInterval = Math.round((double)item[3]) +"—"+ Math.round((double)item[4]);
                            }
                        }
                        if (!results.containsKey(tempName)) {
                            DynamicTemplateTotal dynamicTemplateTotal = new DynamicTemplateTotal();
                            dynamicTemplateTotal.setSimpleLineId(Long.parseLong(item[0].toString()));
                            dynamicTemplateTotal.setName(item[1] + "");
                            dynamicTemplateTotal.setNameCn(tableNameCn);
                            dynamicTemplateTotal.setType(tableType);
                            if (userType) {
                                dynamicTemplateTotal.setCount(Integer.parseInt("0" + item[2]));
                                if (("patrol".equals(dynamicTemplateTotalVM.getDataSource()) || "simpleLine".equals(dynamicTemplateTotalVM.getDataSource()))
                                    && item.length >= 4 && item[3] != null) {
                                    dynamicTemplateTotal.setTime(Integer.parseInt("0" + item[3]));
                                }
                                if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName) && item.length >= 5 && item[4] != null) {
                                    dynamicTemplateTotal.setPatrolMileage(Double.parseDouble("0" + item[4]));
                                }
                            } else {
                                dynamicTemplateTotal.setCount(Integer.parseInt("0" + item[1]));
                                if (("patrol".equals(dynamicTemplateTotalVM.getDataSource()) || "simpleLine".equals(dynamicTemplateTotalVM.getDataSource()))
                                    && item.length >= 3 && item[2] != null && (item[2] instanceof Long || item[2] instanceof Integer)) {
                                    dynamicTemplateTotal.setTime(Integer.parseInt("0" + item[2]));
                                }
                                if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName) && item.length >= 4 && item[3] != null) {
                                    dynamicTemplateTotal.setPatrolMileage(Double.parseDouble("0" + item[3]));
                                }
                            }
                            if(altitudeInterval != null){
                                dynamicTemplateTotal.setAltitudeInterval(altitudeInterval);
                            }
                            results.put(tempName, dynamicTemplateTotal);
                        } else {
                            DynamicTemplateTotal tempDynamicTemplateTotal = results.get(tempName);
                            if (tempDynamicTemplateTotal != null) {
                                tempDynamicTemplateTotal.setType(tableType);
                                tempDynamicTemplateTotal.setNameCn(tableNameCn);
                                if (userType) {
                                    tempDynamicTemplateTotal.setCount(tempDynamicTemplateTotal.getCount() + Integer.parseInt("0" + item[2]));
                                    if (("patrol".equals(dynamicTemplateTotalVM.getDataSource()) || "simpleLine".equals(dynamicTemplateTotalVM.getDataSource()))
                                        && item.length >= 4 && item[3] != null) {
                                        tempDynamicTemplateTotal.setTime(tempDynamicTemplateTotal.getTime() + Integer.parseInt("0" + item[3]));
                                    }
                                    if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName) && item.length >= 5 && item[4] != null) {
                                        tempDynamicTemplateTotal.setPatrolMileage(tempDynamicTemplateTotal.getPatrolMileage() + Double.parseDouble("0" + item[4]));
                                    }
                                } else {
                                    tempDynamicTemplateTotal.setCount(tempDynamicTemplateTotal.getCount() + Integer.parseInt("0" + item[1]));
                                    if (("patrol".equals(dynamicTemplateTotalVM.getDataSource()) || "simpleLine".equals(dynamicTemplateTotalVM.getDataSource()))
                                        && item.length >= 3 && item[2] != null) {
                                        tempDynamicTemplateTotal.setTime(tempDynamicTemplateTotal.getTime() + Integer.parseInt("0" + item[2]));
                                    }
                                    if (patrolMileageFieldName != null && !"".equals(patrolMileageFieldName) && item.length >= 4 && item[3] != null) {
                                        tempDynamicTemplateTotal.setPatrolMileage(tempDynamicTemplateTotal.getPatrolMileage() + Double.parseDouble("0" + item[3]));
                                    }
                                }
                                if(altitudeInterval != null){
                                    tempDynamicTemplateTotal.setAltitudeInterval(altitudeInterval);
                                }
                                results.replace(tempName, tempDynamicTemplateTotal);
                            }
                        }
                    }
                }
            }
        }
        return results;
    }
    // 自定义分析统计
    private HashMap<String, DynamicTemplateTotal> getTotalTemplateForCustomize(DynamicTemplateTotalVM dynamicTemplateTotalVM){
//        // 首先获取查询表的动态表模板，后面会用到
//        String staticTableName = dynamicTemplateTotalVM.getStatisticTable();
//        if(staticTableName.toLowerCase().contains("children")){
//            String[] splitList = staticTableName.toLowerCase().split("children");
//            if(splitList.length > 0){
//                staticTableName = splitList[0];
//            }
//        }
//        String hql1 = String.format("from DynamicTemplate where type='%s' and name = '%s'", dynamicTemplateTotalVM.getDataSource(), staticTableName);
//        List<Object> dynamicTables = this.dynamicTemplateRepository.createQueryList(hql1);
//        HashMap fieldColumnsDomain =  new HashMap<>();
//        if(dynamicTables.size() > 0){
//            // 所有domain都放在主表fieldColumnsDomain中
//            HashMap hashMapObject = (HashMap) dynamicTables.get(0);
//            JSONObject resultTempObject = null;
//            String tempContent = hashMapObject.get("jsonContent").toString();
//            if (tempContent != null && !"".equals(tempContent)) {
//                resultTempObject = (JSONObject) JSON.parse(tempContent);
//                if (resultTempObject.containsKey("fieldColumnsDomain")) {
//                    fieldColumnsDomain = (HashMap) resultTempObject.get("fieldColumnsDomain");
//                }
//            }
//        }

        HashMap<String, DynamicTemplateTotal> results = new HashMap<>();
        String where = String.format("1=1 ");
        if (dynamicTemplateTotalVM != null && dynamicTemplateTotalVM.getStartDateTime() != null) {
            where += String.format(" and createDateTime>='%s'", dateTimeFormatTodayStart.format(dynamicTemplateTotalVM.getStartDateTime()));
        }
        if (dynamicTemplateTotalVM != null && dynamicTemplateTotalVM.getStartDateTime() != null) {
            where += String.format(" and createDateTime<='%s'", dateTimeFormatTodayEnd.format(dynamicTemplateTotalVM.getEndDateTime()));
        }

        // 统计字段
        String statisticFieldCn = dynamicTemplateTotalVM.getStatisticFieldCn();
        String hql = String.format("select %s,count(a) from %s a where %s GROUP BY %s",
            ("a." + statisticFieldCn), dynamicTemplateTotalVM.getStatisticTable(), where, ("a." + statisticFieldCn));
        List<Object> queryList = this.dynamicTemplateRepository.createQueryList(hql);
        if (queryList != null && queryList.size() > 0) {
            for (int i = 0; i < queryList.size(); i++) {
                DynamicTemplateTotal dynamicTemplateTotal = new DynamicTemplateTotal();
                dynamicTemplateTotal.setName(dynamicTemplateTotalVM.getStatisticTable());
                dynamicTemplateTotal.setNameCn(dynamicTemplateTotalVM.getStatisticTableCn());
                dynamicTemplateTotal.setType(dynamicTemplateTotalVM.getDataSource());

                if (queryList.get(i) instanceof Object[]) {
                    Object[] item = ((Object[]) queryList.get(i));
                    String keyName = "空";
                    if(item[0] != null){
                        keyName = item[0].toString();
                    }
                    dynamicTemplateTotal.setStatisticFieldValue(keyName);
                    if(item[1] != null){
                        dynamicTemplateTotal.setCount(Integer.parseInt("0" + item[1]));
                    }else {
                        dynamicTemplateTotal.setCount(Integer.parseInt("0"));
                    }
                    results.put(keyName, dynamicTemplateTotal);
                }
            }
        }
        return results;
    }

    @Override
    public List<Object> totalDynamicTable(String tableName, String where, String geom, String groupField, String totalType, String totalField) throws Exception {
        String totalTypeString = "";
        switch (totalType) {
            case "sum":
            case "求和": {
                totalTypeString = String.format("sum(%S)", totalField);
                break;
            }
            case "avg":
            case "平均": {
                totalTypeString = String.format("avg(%S)", totalField);
                break;
            }
            case "count":
            case "计数": {
                totalTypeString = String.format("count(%S)", totalField);
                break;
            }
        }
        // geom = "{\"rings\":[[[104.14575128123505,30.631849063327373],[104.14575128123505,30.626807549979198],[104.15379994618765,30.626807549979198],[104.15379994618765,30.631849063327373]]],\"spatialReference\":{\"wkid\":4326}}";
        if (where == null || "".equals(where)) {
            where = "1=1";
        }
        if (geom != null && !"".equals(geom)) {
            com.esri.core.geometry.Geometry geometry = null;
            try {
                geometry = GeometryEngine.jsonToGeometry(geom).getGeometry();
            } catch (Exception ex) {
                throw new Exception("Geometry序列化失败");
            }
            geom = GeometryEngine.geometryToWkt(geometry, 0);
        }
        String resultField = String.format("%s,%s,%s", groupField, totalField, totalTypeString + " as " + totalType);
        String groupFieldString = String.format("%s,%s", groupField, totalField);

        if (groupField.equals(totalField)) {
            resultField = String.format("%s,%s", groupField, totalTypeString + " as " + totalType);
            groupFieldString = groupField;
        }

        String sql = String.format("SELECT %s FROM %s where %s and ST_Contains(ST_GeomFromText('%s',4326),geom) group by %s", resultField, "public." + tableName, where, geom, groupFieldString);
        if (geom == null || "".equals(geom)) {
            sql = String.format("SELECT %s FROM %s where %s group by %s", resultField, "public." + tableName, where, groupFieldString);
        }
        List list = this.dynamicTemplateRepository.createSqlQueryList(sql);
        return list;
    }
    /**
     * 统计分析所有表中的某字段
     *
     * @param dynamicTemplateTotalVMs
     * @return
     */
    @Override
    public String getTotalAllTemplate(List<DynamicTemplateTotalVM> dynamicTemplateTotalVMs) {
        if (dynamicTemplateTotalVMs == null || dynamicTemplateTotalVMs.size() == 0) {
            return "error:输入参数为空";
        }
        try {
            HashMap<String, DynamicTemplateTotal> results = new HashMap<>();
            for(int i=0; i< dynamicTemplateTotalVMs.size(); i++){
                HashMap<String, DynamicTemplateTotal> resultList = getTotalTemplateForCustomize(dynamicTemplateTotalVMs.get(i));
                if(results.size() == 0){
                    results = resultList;
                    continue;
                }
                if(resultList.size() > 0){
                    Set<String> keys = resultList.keySet();
                    Iterator<String> iter = keys.iterator();
                    while(iter.hasNext()){
                        String str = iter.next();
                        if(results.containsKey(str)){
                            int oldCount = results.get(str).getCount();
                            results.get(str).setCount(oldCount + resultList.get(str).getCount());
                        }else {
                            results.put(str, resultList.get(str));
                        }
                    }
                }
            }
            return JSON.toJSONStringWithDateFormat(results, "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
        } catch (Exception ex) {
            //session.close();
            log.error(ex.getLocalizedMessage());
            return null;
        }
    }

    /**
     * 历史数据
     *
     * @param dynamicTemplateHistoryVM
     * @return
     */
    @Override
    public HashMap<String, Object> getHistoryTemplate(DynamicTemplateHistoryVM dynamicTemplateHistoryVM) {
        try {
            String where = String.format("1=1 ");
            if (dynamicTemplateHistoryVM.getStartDateTime() != null) {
                where += String.format(" and createDateTime>='%s'", dynamicTemplateHistoryVM.getStartDateTime());
            }
            if (dynamicTemplateHistoryVM.getStartDateTime() != null) {
                where += String.format(" and createDateTime<='%s'", dynamicTemplateHistoryVM.getEndDateTime());
            }
            if (dynamicTemplateHistoryVM.getUsers() != null && dynamicTemplateHistoryVM.getUsers().size() > 0) {
                String para = "";
                for (int i = 0; i < dynamicTemplateHistoryVM.getUsers().size(); i++) {
                    if (i == 0) {
                        para += "'" + dynamicTemplateHistoryVM.getUsers().get(i) + "'";
                    } else {
                        para += ",'" + dynamicTemplateHistoryVM.getUsers().get(i) + "'";
                    }
                }
                where += String.format(" and createAuthor IN (%s)", para);
            }
            if (dynamicTemplateHistoryVM.getDeviceIds() != null && dynamicTemplateHistoryVM.getDeviceIds().size() > 0) {
                String para = "";
                for (int i = 0; i < dynamicTemplateHistoryVM.getDeviceIds().size(); i++) {
                    if (i == 0) {
                        para += "'" + dynamicTemplateHistoryVM.getDeviceIds().get(i) + "'";
                    } else {
                        para += ",'" + dynamicTemplateHistoryVM.getDeviceIds().get(i) + "'";
                    }
                }
                where += String.format(" and deviceId IN (%s)", para);
            }
            // 若为样线监测模板，则需要根据监测样线id筛选
            if(dynamicTemplateHistoryVM.getSimpleLineId() != null && !dynamicTemplateHistoryVM.getSimpleLineId().equals("")){
                Long simpleLineId = Long.parseLong(dynamicTemplateHistoryVM.getSimpleLineId());
                where += String.format(" and jianceyangxian='%s' ", simpleLineId);
            }
            String hql = String.format("from %s where %s order by createDateTime desc", dynamicTemplateHistoryVM.getTempName(), where);

            List<Object> dynamicTable = null;
            if (dynamicTemplateHistoryVM.getPageIndex() != null && dynamicTemplateHistoryVM.getPageSize() != null) {
                dynamicTable = this.dynamicTemplateRepository.createQueryList(hql, dynamicTemplateHistoryVM.getPageIndex(), dynamicTemplateHistoryVM.getPageSize());
            } else {
                dynamicTable = this.dynamicTemplateRepository.createQueryList(hql);
            }
            String countHql = String.format("select count(*) from %s where %s", dynamicTemplateHistoryVM.getTempName(), where);
            Integer count = this.dynamicTemplateRepository.createQueryCount(countHql);
            HashMap<String, Object> resultHashMap = new HashMap<>();
            resultHashMap.put("rows", dynamicTable);
            resultHashMap.put("count", count);
            return resultHashMap;
        } catch (Exception ex) {
            //session.close();
            log.error(ex.getLocalizedMessage());
            return null;
        }
    }

    /**
     * 导出历史记录
     *
     * @param dynamicTemplateHistoryVM
     * @return
     */
    @Override
    public String exportHistoryTemplate2Excel(DynamicTemplateHistoryVM dynamicTemplateHistoryVM) {
        try {
            //List<Object> dynamicTables = this.getHistoryTemplate(dynamicTemplateHistoryVM);
            HashMap<String, Object> historyData = this.getHistoryTemplate(dynamicTemplateHistoryVM);
            List<Object> dynamicTables = (List<Object>) historyData.get("rows");
            if (dynamicTables == null || dynamicTables.size() <= 0) {
                return null;
            }
            HashMap jsonObject = ((HashMap) dynamicTables.get(0));
            List<String> headers = new ArrayList<>();   // {"学号", "姓名", "年龄", "性别", "出生日期"};
            Object[] keys = jsonObject.keySet().toArray();
            for (int i = 0; i < keys.length; i++) {
                String key = keys[i].toString();
                if (!key.toLowerCase().contains("children") && !key.toLowerCase().contains("$type$") && !key.equals("id")) {
                    headers.add(keys[i].toString());
                }
            }
            try {
                //String rootPath = ResourceUtils.getFile("classpath:attached/placeholder.txt").getParent();
                String rootPath = getApplicationPath();
                String fileName = UUID.randomUUID().toString() + ".xls";

                OutputStream out = new FileOutputStream(rootPath + File.separator + fileName);
                export2ExcelServiceImpl.exportExcel("历史数据", headers, headers, dynamicTables, out);


                out.close();
                System.out.println("excel导出成功:" + fileName);
                return fileName;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        } catch (Exception ex) {
            log.error(ex.getLocalizedMessage());
            return null;
        }
    }


    /**
     * 从数据库生成hbm.xml文件
     *
     * @return
     */
    @Override
    public Boolean generateXmlFromDatabase() {
        //Session session = getSessionFactory().openSession();
        String hbmXmlPath = this.dynamicTemplateRepository.addResource();
        boolean isFind = false;
        try {
            List<Object> dynamicTables = this.dynamicTemplateRepository.createQueryList("from DynamicTemplate");// session.createQuery("from DynamicTemplate").list();
            if (dynamicTables != null && dynamicTables.size() > 0) {
                for (int i = 0; i < dynamicTables.size(); i++) {
                    HashMap dynamicTable = (HashMap) dynamicTables.get(i);
                    Object childrenXmlObject = dynamicTable.get("childrenXml");
                    if (childrenXmlObject != null) {
                        PersistentSet persistentSet = (PersistentSet) childrenXmlObject;
                        if (persistentSet != null) {
                            Object[] childrenXmlsHashMap = persistentSet.toArray();
                            if (childrenXmlsHashMap != null && childrenXmlsHashMap.length > 0) {
                                for (int j = 0; j < childrenXmlsHashMap.length; j++) {
                                    HashMap childrenXmlHashMap = (HashMap) childrenXmlsHashMap[j];    //.get(j);
                                    String xmlFileName = (String) childrenXmlHashMap.get("xmlFileName");
                                    String xmlContent = (String) childrenXmlHashMap.get("xmlContent");
                                    try {
                                        createFile(hbmXmlPath, xmlFileName);
                                        writeFile(hbmXmlPath, xmlFileName, xmlContent);
                                        isFind = true;
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (isFind == true) {
                this.dynamicTemplateRepository.setSessionFactoryNull();  // this._sessionFactory = null;
            }
            //session.close();
            return true;
        } catch (Exception ex) {
            //session.close();
            return false;
        }
    }

    /**
     * 保存动态模板数据（保存动态表单数据）
     *
     * @return
     */

    //@CachePut(value = "DefaultDynamicTemplate_getAllRecords",key="#dynamicTemplate.getId()")   //因为查询所有数据时缓存有问题
    @CacheEvict(value = "DefaultDynamicTemplate_getAllRecords", allEntries = true)
    @Override
    public String saveDynamicTable(DynamicTemplate dynamicTemplate) {
        HashMap<String, Object> resultMap = new HashMap<>();
        if (dynamicTemplate == null || dynamicTemplate.getRows() == null) {
            resultMap.put("message", "传入参数为空");
            resultMap.put("success", false);
            return JSON.toJSONString(resultMap);
        }
        if (dynamicTemplate.getName() == null) {
            resultMap.put("message", "传入参数为空");
            resultMap.put("success", false);
            return JSON.toJSONString(resultMap);
        }

        if(dynamicTemplate.getFieldColumns()==null){
           HashMap temp_dynamic_table=(HashMap) this.getDynamicTemplateByName(getPingYin(dynamicTemplate.getName()));
           if(temp_dynamic_table !=null){
               if (dynamicTemplate.getLandType()==null && temp_dynamic_table.get("landType") !=null) {
                   dynamicTemplate.setLandType(temp_dynamic_table.get("landType").toString());
               }
               if(dynamicTemplate.getType()==null && temp_dynamic_table.get("type") !=null){
                   dynamicTemplate.setType(temp_dynamic_table.get("type").toString());
               }
               String tempContent = (temp_dynamic_table).get("jsonContent").toString();
               if (tempContent != null && !"".equals(tempContent)) {
                   JSONObject tempObject = (JSONObject) JSON.parse(tempContent);
                   if (tempObject != null && temp_dynamic_table != null && temp_dynamic_table.size() > 0) {
                       JSONArray jsonArray=(JSONArray)tempObject.get("fieldColumns");
                       String temp_json= JSON.toJSONString(jsonArray);
                       dynamicTemplate.setFieldColumns(JSON.parseArray(temp_json,FieldColumn.class));
                       // dynamicTemplate.setFieldColumnsDomain((HashMap<String, Object>)tempObject.get("fieldColumnsDomain"));
                   }
               }
           }
        }


        try {
            // 查找要删除的行
            List<String> delChildName = new ArrayList<>();
            List<DynamicTemplate> dynamicTemplates = dynamicTemplate.getChildrenTable();
            if (dynamicTemplates != null) {
                for (int i = 0; i < dynamicTemplates.size(); i++) {
                    DynamicTemplate tempDynamicTemplate = dynamicTemplates.get(i);
                    if ("del".equals(tempDynamicTemplate.getAddOrDel())) {
                        delChildName.add(tempDynamicTemplate.getDescription());
                    }
                }
            }

            HashMap<String, Object> photoList = new HashMap<String, Object>();
            HashMap<String, Object> rows = (HashMap<String, Object>) dynamicTemplate.getRows();
            this.repairFieldType(dynamicTemplate.getFieldColumns(), rows, photoList);

            // 将ArrayList替换成Set，否者保存失败
            Object[] keys = rows.keySet().toArray();
            for (int i = 0; i < keys.length; i++) {
                String keyName = keys[i].toString();
                Object valueObject = rows.get(keyName);
                if (valueObject instanceof ArrayList) {
                    ArrayList valueObjectArrayList = (ArrayList) valueObject;
//                    Set setChildArrayList = new HashSet(valueObjectArrayList);
//                    rows.replace(keyName, setChildArrayList);
                    for (int j = 0; j < valueObjectArrayList.size(); j++) {
                        Object tempObj = valueObjectArrayList.get(j);
                        if (tempObj instanceof HashMap) {
                            HashMap valueObjectHashMap = (HashMap) valueObjectArrayList.get(j);
                            if (valueObjectHashMap.containsKey("createDateTime")) {
                                Object tempValue = valueObjectHashMap.get("createDateTime");
                                if (tempValue.toString().contains(" ")) {
                                    valueObjectHashMap.replace("createDateTime", simpleDateFormat.parse(tempValue.toString()));
                                } else {
                                    valueObjectHashMap.replace("createDateTime", simpleDateFormat2.parse(tempValue.toString()));
                                }
                            }
                            //转换gps点中x、y、z的值
                            if (valueObjectHashMap.containsKey("x")) {
                                Object tempValueX = valueObjectHashMap.get("x");
                                valueObjectHashMap.replace("x", Double.parseDouble(tempValueX.toString()));
                            }
                            if (valueObjectHashMap.containsKey("y")) {
                                Object tempValueY = valueObjectHashMap.get("y");
                                valueObjectHashMap.replace("y", Double.parseDouble(tempValueY.toString()));
                            }
                            if (valueObjectHashMap.containsKey("z")) {
                                Object tempValueZ = valueObjectHashMap.get("z");
                                valueObjectHashMap.replace("z", Double.parseDouble(tempValueZ.toString()));
                            }
                            if (valueObjectHashMap.containsKey("jianceyangxian")) {
                                Object tempValueSimpleLineId = valueObjectHashMap.get("jianceyangxian");
                                valueObjectHashMap.replace("jianceyangxian", Long.parseLong(tempValueSimpleLineId.toString()));
                            }
                            if (dynamicTemplate.getChildrenTable() != null) {
                                Optional<DynamicTemplate> tempDynamicTemplate = dynamicTemplate.getChildrenTable().stream().filter((item) -> keyName.equals(item.getDescription())).findFirst();
                                if (tempDynamicTemplate != null && tempDynamicTemplate.isPresent()) {
                                    this.repairFieldType(tempDynamicTemplate.get().getFieldColumns(), valueObjectHashMap, photoList);
                                }
                            }
                        }
                    }

                }
                if (delChildName != null && delChildName.size() > 0 && delChildName.contains(keyName)) {
                    String delHql = String.format("delete %s a where a.parentId='%s'", keyName, ((HashMap<String, Object>) dynamicTemplate.getRows()).get("id"));
                    //Query query = session.createQuery(delHql);
                    //query.executeUpdate();
                    this.dynamicTemplateRepository.createQueryUpate(delHql);
                }
            }
            //将createDateTime替换为空(此字段值为数据库赋值)
            rows.replace("createDateTime", null);
            if (!rows.containsKey("id")) {
                if (dynamicTemplate.getId() != null && !"".equals(dynamicTemplate.getId())) {
                    rows.put("id", dynamicTemplate.getId());
                } else {
                    rows.put("id", UUID.randomUUID().toString());
                }
            } else {
                if (rows.get("id") == null) {
                    if (dynamicTemplate.getId() != null && !"".equals(dynamicTemplate.getId())) {
                        rows.replace("id", dynamicTemplate.getId());
                    } else {
                        rows.replace("id", UUID.randomUUID().toString());
                    }
                }
            }
//
//            session = getSessionFactory().openSession();
//            Transaction tx = session.beginTransaction();
//            session.merge(getPingYin(dynamicTemplate.getName()), rows);
//            tx.commit();
//            session.close();

            String saveMessage = this.dynamicTemplateRepository.saveDynamicTable(getPingYin(dynamicTemplate.getName()), rows);
            if (saveMessage == null) {
                this.savePicture2File(photoList);

                resultMap.put("message", "保存成功");
                resultMap.put("tableName", dynamicTemplate.getName());
                resultMap.put("id", dynamicTemplate.getId());
                resultMap.put("success", true);
            } else {
                resultMap.put("message", "保存失败：" + saveMessage);
                resultMap.put("tableName", dynamicTemplate.getName());
                resultMap.put("id", dynamicTemplate.getId());
                resultMap.put("success", false);
            }
            return JSON.toJSONString(resultMap);
        } catch (Exception ex) {
            if (ex.getMessage() == null || "".equals(ex.getMessage())) {
                resultMap.put("message", "保存失败：" + ex.getMessage());
                resultMap.put("tableName", dynamicTemplate.getName());
                resultMap.put("id", dynamicTemplate.getId());
            } else {
                resultMap.put("message", "保存失败：" + ex.toString());
                resultMap.put("tableName", dynamicTemplate.getName());
                resultMap.put("id", dynamicTemplate.getId());
            }
            resultMap.put("success", false);
            return JSON.toJSONString(resultMap);
        }
    }

    /**
     * 创建模板（表单）
     *
     * @return
     */
    //@CacheEvict(value = {"DefaultDynamicTemplate_getAllRecords"}, allEntries = true)
    @CacheEvict(value = {"DefaultDynamicTemplateCache", "DefaultDynamicTemplateCache2", "DefaultDynamicTemplate_getAllRecords"}, allEntries = true)
    @Override
    public String createTemplate(DynamicTemplate dynamicTemplate) {
        Boolean success = false;
        String resultString = "保存失敗";
        if (dynamicTemplate == null) {
            resultString = "传入参数为空";
        }
        if (dynamicTemplate.getName() == null) {
            resultString = "模板名称为空";
        }
        if (dynamicTemplate != null && dynamicTemplate.getName() != null) {
            String entityName = getPingYin(dynamicTemplate.getName());
            String entity = this.dynamicTemplateRepository.getByEntity(entityName);
            if (entity == null) {
                boolean isOk = this.generateHbm(entityName, dynamicTemplate);
                if (isOk) {
                    boolean isSave = this.saveDynamic2Database(entityName, dynamicTemplate);
                    if (isSave) {
                        success = true;
                        resultString = "生成数据库结构成功";
                    } else {
                        resultString = "生成数据库结构失败";
                    }
                } else {
                    resultString = "生成hbm失败";
                }
            } else {    // 更新数据
                this.generateHbm(entityName, dynamicTemplate);
                this.dynamicTemplateRepository.delDynamicFromDatabase(getPingYin(dynamicTemplate.getName()));
                boolean isSave = this.saveDynamic2Database(entityName, dynamicTemplate);
                if (isSave) {
                    success = true;
                    resultString = "更新表结构json成功";
                } else {
                    resultString = "更新表结构json失败";
                }
            }
        }
        if (success == true) {
            String hql = String.format("update DynamicTemplate set updateUser=''");
            this.dynamicTemplateRepository.createQueryUpate(hql);
        }

        this.dynamicTemplateRepository.setSessionFactoryNull();
        HashMap<String, Object> result = new HashMap<>();
        result.put("success", success);
        result.put("message", resultString);
        return JSON.toJSONString(result);
    }

    @Cacheable(value = "DefaultDynamicTemplateCache", key = "#type")
    //@CachePut(value="guavaDemo" ,key="#id + 'dataMap'")
    @Override
    public String queryDynamicTemplate(String type) {
        //Session session = getSessionFactory().openSession();
        try {
            String hql = String.format("from DynamicTemplate where type='%s' order by sorting", type);
            List<Object> dynamicTable = this.dynamicTemplateRepository.createQueryList(hql); //session.createQuery(hql).list();
            if (dynamicTable != null) {
                for (int i = 0; i < dynamicTable.size(); i++) {
                    HashMap hashMapObject = (HashMap) dynamicTable.get(i);
                    if (hashMapObject != null) {
                        if (hashMapObject.containsKey("childrenXml")) {
                            hashMapObject.remove("childrenXml");
                        }
                        String tableName = hashMapObject.get("name").toString();
                        hql = String.format("select count(*) from %s", tableName);
                        int count = ((Number) this.dynamicTemplateRepository.createQueryObject(hql)).intValue();      // ((Number) session.createQuery(hql).uniqueResult()).intValue();
                        hashMapObject.put("count", count);

                        hql = String.format("from %s ORDER BY createDateTime desc", tableName);
                        //Query query = session.createQuery(hql);
                        //query.setMaxResults(1);
                        //List<Object> tempObject = query.getResultList();
                        List<Object> tempObject = this.dynamicTemplateRepository.createQueryListTopN(hql, 1);
                        if (tempObject != null && tempObject.size() > 0) {
                            hashMapObject.put("top1", tempObject.get(0));
                        }
                    }
                }
            }
            //
            //
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
            String result = gson.toJson(dynamicTable);
            return result;
            //String result = JSON.toJSONStringWithDateFormat(dynamicTable, "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
            ////session.close();
            //return result;
        } catch (Exception ex) {
            //session.close();
            log.error(ex.getLocalizedMessage());
            return null;
        }
    }

    @Override
    @Cacheable(value = "DefaultDynamicTemplateCache2")
    public String queryDynamicTemplate2(String type) {
        //Session session = getSessionFactory().openSession();
        String hql = String.format("from DynamicTemplate where type='%s' order by sorting", type);

        if (type == null || "".equals(type) || "null".equals(type)) {
            hql = String.format("from DynamicTemplate  order by sorting");
        }
        String result = null;
        this.dynamicTemplateRepository.getByEntity("DynamicTemplate");
        List<Object> dynamicTable = this.dynamicTemplateRepository.createQueryList(hql);// session.createQuery(hql).list();
        if (dynamicTable != null && dynamicTable.size() > 0) {
            result = JSON.toJSONStringWithDateFormat(dynamicTable, "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
        }
        return result;
    }

    @Override
    public String queryDynamicTemplate2(String type, String userName) {
        //Session session = getSessionFactory().openSession();
        String hql = String.format("from DynamicTemplate where type='%s'", type);
        String countHql2 = String.format("select count(*) from DynamicTemplate where type='%s'", type);
        String countHql = ("select count(*) from DynamicTemplate where type='" + type + "' and updateUser not like '%" + userName + "%'");
        if (userName != null) {
            countHql = ("select count(*) from DynamicTemplate where type='" + type + "'  and updateUser not like '%" + userName + "%'");
        }
        if (type == null || "".equals(type) || "null".equals(type)) {
            hql = String.format("from DynamicTemplate");
            countHql2 = String.format("select count(*) from DynamicTemplate");
            if (userName != null) {
                countHql = ("select count(*) from DynamicTemplate where updateUser not like '%" + userName + "%'");
            }
        }
        HashMap<String, Object> tempResult = new HashMap<>();
        //String result = null;
        this.dynamicTemplateRepository.getByEntity("DynamicTemplate");
        Integer count = this.dynamicTemplateRepository.createQueryCount(countHql);
        if (count > 0) {
            List<Object> dynamicTable = this.dynamicTemplateRepository.createQueryList(hql);// session.createQuery(hql).list();
            if (dynamicTable != null && dynamicTable.size() > 0) {
                tempResult.put("content", dynamicTable);
                tempResult.put("count", dynamicTable.size());
            }
        } else {
            tempResult.put("count", this.dynamicTemplateRepository.createQueryCount(countHql2));
            tempResult.put("content", null);
        }
        return JSON.toJSONStringWithDateFormat(tempResult, "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 删除指定用户已更新状态
     *
     * @param userName
     * @return
     */
    @Override
    public Boolean deleteUpdatedDynamicTemplate(String userName) {
        try {
            String hql = null;
            String countHql = ("select count(*) from DynamicTemplate where updateUser like '%" + userName + "%'");
            int count = this.dynamicTemplateRepository.createQueryCount(countHql);
            if (count > 0) {
                hql = String.format("update DynamicTemplate set updateUser=REPLACE(updateUser,'|%s','')", userName);
            }
            if (hql != null) {
                return this.dynamicTemplateRepository.createQueryUpate(hql);
            } else {
                return false;
            }
        } catch (Exception ex) {
            return false;
        }
    }

    /**
     * 更新动态表用户
     *
     * @param userName
     * @return
     */
    @Override
    public Boolean updateDynamicTemplateUser(String userName) {
        try {
            String hql = String.format("update DynamicTemplate set updateUser=CONCAT(updateUser,'|%s')", userName);
            return this.dynamicTemplateRepository.createQueryUpate(hql);
        } catch (Exception ex) {
            return false;
        }
    }

    @Override
    public String getDynamicTable(String entityName) {
        return this.dynamicTemplateRepository.getDynamicTable(entityName);
    }

    @Override
    public String getDynamicTable(String entityName, String where) {
        return this.dynamicTemplateRepository.getDynamicTable(entityName, where);
    }

    /**
     * 处理图片数据、日期型类型、Double类型
     *
     * @param fieldColumns
     * @param tempRows
     * @param photoList
     */
    private void repairFieldType(List<FieldColumn> fieldColumns, HashMap<String, Object> tempRows, HashMap<String, Object> photoList) {
        // 处理图片数据、日期型类型、Double类型,geometry字段赋值等操作
        Double tempLongitude = null;
        Double tempLatitude = null;
        Double tempAltitude = null;
        final String geomName = "geom";
        for (int i = 0; i < fieldColumns.size(); i++) {
            FieldColumn fieldColumn = fieldColumns.get(i);
            String filedName = fieldColumn.getFieldName();
            String fileType = fieldColumn.getFieldType();
            if (fileType == null || "".equals(fileType)) {
                fileType = fieldColumn.getFrontType();
            }
            switch (fileType) {
                case "recordGpsLocation":
                    filedName = filedName + "Length";
                    Object tempGpsLengthValue = tempRows.get(filedName);
                    if (tempGpsLengthValue != null && !"".equals(tempGpsLengthValue)) {
                        try {
                            tempRows.replace(filedName, Double.parseDouble(tempGpsLengthValue.toString()));
                        } catch (Exception ex) {
                            log.warn("saveDynamicTable：转换Double类型出错：", ex);
                        }
                    }
                    break;
                case "startDateTime":
                case "endDateTime":
                case "date":
                    Object tempValue = tempRows.get(filedName);
                    if (tempValue != null && !"".equals(tempValue)) {
                        try {
                            if (tempValue.toString().contains(" ")) {
                                tempRows.replace(filedName, simpleDateFormat.parse(tempValue.toString()));
                            } else {
                                tempRows.replace(filedName, simpleDateFormat2.parse(tempValue.toString()));
                            }
                        } catch (Exception ex) {
                            log.warn("saveDynamicTable：转换日期类型出错：", ex);
                        }
                    }
                    break;
                case "number":
                case "int":
                    Object tempIntValue = tempRows.get(filedName);
                    if (tempIntValue != null && !"".equals(tempIntValue)) {
                        try {
                            tempRows.replace(filedName, Integer.parseInt(tempIntValue.toString()));
                        } catch (Exception ex) {
                            log.warn("saveDynamicTable：转换int类型出错：", ex);
                        }
                    }
                    break;
                case "simpleLine":
                    Object tempLongValue = tempRows.get(filedName);
                    if (tempLongValue != null && !"".equals(tempLongValue)) {
                        try {
                            tempRows.replace(filedName, Long.parseLong(tempLongValue.toString()));
                        } catch (Exception ex) {
                            log.warn("saveDynamicTable：转换Long类型出错：", ex);
                        }
                    }
                    break;
                case "locationX":
                case "locationY":
                case "locationZ":
                case "locationXNoEdit":
                case "locationYNoEdit":
                case "locationZNoEdit":
                case "double":
                    Object tempDoubleValue = tempRows.get(filedName);
                    if (tempDoubleValue != null && !"".equals(tempDoubleValue)) {
                        Double doubleValue = 0.0;
                        try {
                            doubleValue = Double.parseDouble(tempDoubleValue.toString());
                            tempRows.replace(filedName, doubleValue);
                            if ("locationX".equals(fileType) || "locationXNoEdit".equals(fileType)) {
                                tempLongitude = doubleValue;
                            } else if ("locationY".equals(fileType) || "locationYNoEdit".equals(fileType)) {
                                tempLatitude = doubleValue;
                            } else if ("locationZ".equals(fileType) || "locationZNoEdit".equals(fileType)) {
                                tempAltitude = doubleValue;
                            }
                        } catch (Exception ex) {
                            log.warn("saveDynamicTable：转换double类型出错：", ex);
                        }
                    }
                    break;
                case "image":
                case "imageMultiple":
                case "signature":
                case "signatureMultiple":
                    Object imageObject = tempRows.get(filedName + "PhotoChildren");
                    if (imageObject != null) {
                        ArrayList tempImageValue = (ArrayList) imageObject;
                        if (tempImageValue != null && tempImageValue.size() > 0) {
                            for (int j = 0; j < tempImageValue.size(); j++) {
                                HashMap tempHashMap = (HashMap) tempImageValue.get(j);
                                photoList.put(tempHashMap.get("id").toString(), tempHashMap.get("photoContent"));
                                tempHashMap.replace("photoContent", null);
                            }
                        }
                    } else {
                        Object tempImageObject = tempRows.get(filedName);
                        if (tempImageObject == null || "".equals(tempImageObject)) {
                            if (tempRows.containsKey(filedName)) {
                                //tempRows.replace(filedName, UUID.randomUUID().toString());
                            } else {
                                tempRows.put(filedName, UUID.randomUUID().toString());
                            }
                        }
                    }
                    break;
                case "audio":
                    Object audioObject = tempRows.get(filedName + "AudioChildren");
                    if (audioObject == null) {
                        Object tempAudioObject = tempRows.get(filedName);
                        if (tempAudioObject == null || "".equals(tempAudioObject)) {
                            if (tempRows.containsKey(filedName)) {
                                //tempRows.replace(filedName, UUID.randomUUID().toString());
                            } else {
                                tempRows.put(filedName, UUID.randomUUID().toString());
                            }
                        }
                    }
                    break;
                case "geometryPolyline":
                    Object polylineObject = tempRows.get(filedName);
                    // INSERT INTO public.caoyuanquequan(id,geom)VALUES (100011,st_geomfromText('POLYGON((122.10243474277 37.586913554557,122.10397969516 37.587385623344,122.10500966342 37.587385623344,122.10496674808 37.587771861442,122.10470925601 37.58785769213,122.10552464755 37.588329760917,122.10827122959 37.588286845573,122.1081853989 37.588544337638,122.1088720444 37.588715999015,122.10947285922 37.588587252982,122.10938702854 37.587213961967,122.11144696506 37.587128131278,122.11123238834 37.588887660392,122.11106072696 37.589188067802,122.11161862644 37.589445559867,122.11161862644 37.590132205375,122.11123238834 37.590518443473,122.11157571109 37.59069010485,122.11127530368 37.591162173637,122.11157571109 37.591376750358,122.11629639896 37.591376750358,122.11659680637 37.591033427604,122.11638222965 37.590561358817,122.11676846774 37.590475528129,122.11629639896 37.589230983146,122.11676846774 37.58927389849,122.1163393143 37.587128131278,122.1163393143 37.58704230059,122.11891423496 37.58704230059,122.11869965824 37.588544337638,122.11951504978 37.588587252982,122.11985837253 37.588329760917,122.11985837253 37.588201014884,122.12260495456 37.588201014884,122.12320576938 37.587900607474,122.123034108 37.58704230059,122.12427865299 37.587171046622,122.12573777469 37.586613147147,122.12582360538 37.586527316459,122.12522279056 37.584553210624,122.12487946781 37.584553210624,122.11586724552 37.584767787345,122.11616765293 37.583651988395,122.11123238834 37.583823649772,122.11170445712 37.584767787345,122.10625420841 37.584896533378,122.10569630893 37.584681956657,122.10307847293      37.584639041312,122.10303555759 37.584681956657,122.10243474277 37.586913554557))', 4326));
                    if (polylineObject==null){
                        polylineObject = tempRows.get(geomName);
                    }
                    if (polylineObject != null) {
                        ArrayList jsonArray = (ArrayList) polylineObject;
                        Integer srid = 4326;
                        if (applicationProperties.getSrid() != null) {
                            srid = applicationProperties.getSrid();
                        }
                        GeometryFactory factory = new GeometryFactory();  // getGeometry().getFactory();
                        Coordinate[] coordinates = new Coordinate[jsonArray.size() + 1];
                        Double x0 = 0.0;
                        Double y0 = 0.0;
                        for (int j = 0; j < jsonArray.size(); j++) {
                            ArrayList xy = (ArrayList) jsonArray.get(j);
                            if (xy.size() >= 2 && xy.get(0) != null && xy.get(1) != null) {
                                coordinates[j] = new Coordinate((Double) xy.get(0), (Double) xy.get(1));
                                if (j == 0) {
                                    x0 = coordinates[0].x;
                                    y0 = coordinates[0].y;
                                }
                            }

                        }
                        coordinates[jsonArray.size()] = new Coordinate(x0, y0);
                        LinearRing lr = factory.createLinearRing(coordinates);
                        lr.setSRID(srid);
                        if (tempRows.containsKey(geomName)) {
                            tempRows.replace(geomName, lr);
                        } else {
                            tempRows.put(geomName, lr);
                        }
                    }
                    break;
                case "geometryPolygon":
                    Object polygonObject = tempRows.get(filedName);
                    // INSERT INTO public.caoyuanquequan(id,geom)VALUES (100011,st_geomfromText('POLYGON((122.10243474277 37.586913554557,122.10397969516 37.587385623344,122.10500966342 37.587385623344,122.10496674808 37.587771861442,122.10470925601 37.58785769213,122.10552464755 37.588329760917,122.10827122959 37.588286845573,122.1081853989 37.588544337638,122.1088720444 37.588715999015,122.10947285922 37.588587252982,122.10938702854 37.587213961967,122.11144696506 37.587128131278,122.11123238834 37.588887660392,122.11106072696 37.589188067802,122.11161862644 37.589445559867,122.11161862644 37.590132205375,122.11123238834 37.590518443473,122.11157571109 37.59069010485,122.11127530368 37.591162173637,122.11157571109 37.591376750358,122.11629639896 37.591376750358,122.11659680637 37.591033427604,122.11638222965 37.590561358817,122.11676846774 37.590475528129,122.11629639896 37.589230983146,122.11676846774 37.58927389849,122.1163393143 37.587128131278,122.1163393143 37.58704230059,122.11891423496 37.58704230059,122.11869965824 37.588544337638,122.11951504978 37.588587252982,122.11985837253 37.588329760917,122.11985837253 37.588201014884,122.12260495456 37.588201014884,122.12320576938 37.587900607474,122.123034108 37.58704230059,122.12427865299 37.587171046622,122.12573777469 37.586613147147,122.12582360538 37.586527316459,122.12522279056 37.584553210624,122.12487946781 37.584553210624,122.11586724552 37.584767787345,122.11616765293 37.583651988395,122.11123238834 37.583823649772,122.11170445712 37.584767787345,122.10625420841 37.584896533378,122.10569630893 37.584681956657,122.10307847293      37.584639041312,122.10303555759 37.584681956657,122.10243474277 37.586913554557))', 4326));
                    if (polygonObject==null){
                        polygonObject = tempRows.get(geomName);
                    }
                    if (polygonObject != null) {
                        ArrayList jsonArray = (ArrayList) polygonObject;
                        Integer srid = 4326;
                        if (applicationProperties.getSrid() != null) {
                            srid = applicationProperties.getSrid();
                        }
                        GeometryFactory factory = new GeometryFactory();  // getGeometry().getFactory();
                        Coordinate[] coordinates = new Coordinate[jsonArray.size() + 1];
                        Double x0 = 0.0;
                        Double y0 = 0.0;
                        for (int j = 0; j < jsonArray.size(); j++) {
                            ArrayList xy = (ArrayList) jsonArray.get(j);
                            if (xy.size() >= 2 && xy.get(0) != null && xy.get(1) != null) {
                                coordinates[j] = new Coordinate((Double) xy.get(0), (Double) xy.get(1));
                                if (j == 0) {
                                    x0 = coordinates[0].x;
                                    y0 = coordinates[0].y;
                                }
                            }

                        }
                        coordinates[jsonArray.size()] = new Coordinate(x0, y0);
                        LinearRing lr = factory.createLinearRing(coordinates);
                        Polygon polygon = factory.createPolygon(lr, new LinearRing[]{});
                        polygon.setSRID(srid);

                        if (tempRows.containsKey(geomName)) {
                            tempRows.replace(geomName, polygon);
                        } else {
                            tempRows.put(geomName, polygon);
                        }
                    }
                    break;
            }
        }
        if (tempLongitude != null && tempLatitude != null) {
            Integer srid = 4326;
            if (applicationProperties.getSrid() != null) {
                srid = applicationProperties.getSrid();
            }
            Point point = geometryUtil.createPoint(tempLongitude, tempLatitude, srid);
            if (tempRows.containsKey(geomName)) {
                tempRows.replace(geomName, point);
            } else {
                tempRows.put(geomName, point);
            }
        }

    }

    @Override
    @Cacheable(value = "DefaultDynamicTemplate_getAllRecords")
    public String getAllRecords(String userName, String entityName, Pageable pageable) {
        //Session session = getSessionFactory().openSession();
        String hql = String.format("from %s ORDER BY createDateTime desc", entityName);
        if (userName != null && !"".equals(userName)) {
            hql = String.format("from %s  where createAuthor='%s' ORDER BY createDateTime desc", entityName, userName);
        }
        List<Object> dynamicTable = this.dynamicTemplateRepository.createQueryList(hql); // session.createQuery(hql).list();
//
//        // 替换geom的值，否则fastjson tojson出错
//        final String geomFieldName = "geom";
//        if (dynamicTable != null && dynamicTable.size() > 0) {
//            for (int i = 0; i < dynamicTable.size(); i++) {
//                HashMap dynamicHashMap = (HashMap) dynamicTable.get(i);
//                if (dynamicHashMap != null && dynamicHashMap.size() > 0) {
//                    Object[] keys = dynamicHashMap.keySet().toArray();
//                    if (dynamicHashMap.containsKey(geomFieldName) && dynamicHashMap.get(geomFieldName) != null) {
//                        dynamicHashMap.replace(geomFieldName, dynamicHashMap.get(geomFieldName).toString());
//                    }
//                    for (int j = 0; j < keys.length; j++) {
//                        Object objectValue = dynamicHashMap.get(keys[j]);
//                        if (objectValue instanceof PersistentSet) {
//                            PersistentSet persistentSet = (PersistentSet) objectValue;
//                            Object[] objectChilds = persistentSet.toArray();
//                            for (int k = 0; k < objectChilds.length; k++) {
//                                HashMap hashMapChild = (HashMap) objectChilds[k];
//                                if (hashMapChild != null && hashMapChild.containsKey(geomFieldName) && hashMapChild.get(geomFieldName) != null) {
//                                    hashMapChild.replace(geomFieldName, hashMapChild.get(geomFieldName).toString());
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        String result = gson.toJson(dynamicTable);
//        String result = JSON.toJSONStringWithDateFormat(dynamicTable, "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
        //session.close();
        return result;
//        Gson gson = new Gson();
//        String result = gson.toJson(dynamicTable);
//        return result;
    }

    @Override
//    @Cacheable(value = "DefaultDynamicTemplate_getAllRecords")
    public String getAllSimpleLineRecords(String userName, String entityName, Long simpleLineId) {
        String hql = String.format("from %s where jianceyangxian='%s' ORDER BY createDateTime desc", entityName, simpleLineId);
        if (userName != null && !"".equals(userName)) {
            hql = String.format("from %s where createAuthor='%s' and jianceyangxian='%s' ORDER BY createDateTime desc", entityName, userName, simpleLineId);
        }
        List<Object> dynamicTable = this.dynamicTemplateRepository.createQueryList(hql); // session.createQuery(hql).list();
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        String result = gson.toJson(dynamicTable);
        return result;
    }

    @Override
    public String getTemplate(String entityName, String id) {

        //Session session = getSessionFactory().openSession();
        Object dynamicTemplate = this.dynamicTemplateRepository.get(DynamicTemplateClassName, entityName); //session.get(DynamicTemplateClassName, entityName);
        String hql = "from " + entityName;
        List<Object> dynamicTable = null;
        if (id != null && !"".equals(id) && !"null".equals(id) && !"undefined".equals(id)) {
            hql += " where id='" + id + "'";
            dynamicTable = this.dynamicTemplateRepository.createQueryList(hql);  // session.createQuery(hql).list();
        } else {
            id = null;
        }
        String tempContent = ((HashMap) dynamicTemplate).get("jsonContent").toString();
        if (tempContent != null && !"".equals(tempContent)) {
            JSONObject tempObject = (JSONObject) JSON.parse(tempContent);
            if (tempObject != null && dynamicTable != null && dynamicTable.size() > 0) {
                HashMap hashMapRow = (HashMap) dynamicTable.get(0);
                if (hashMapRow.containsKey("geom") && hashMapRow.get("geom") != null) {
                    hashMapRow.replace("geom", hashMapRow.get("geom").toString());
                }
                tempObject.replace("rows", hashMapRow);

                if (tempObject.containsKey("rows")) {
                    tempObject.replace("rows", hashMapRow);
                } else {
                    tempObject.put("rows", hashMapRow);
                }
            } else {
                // 创建空的结构
                JSONObject jsonObject = new JSONObject();
                JSONArray jsonArrayChildren = (JSONArray) tempObject.get("childrenTable");
                if (jsonArrayChildren != null && jsonArrayChildren.size() > 0) {
                    for (int i = 0; i < jsonArrayChildren.size(); i++) {
//                        JSONObject object = (JSONObject) jsonArrayChildren.get(i);
//                        HashMap<String, Object> hashMapChildren = this.setTempRows(object);
                        JSONArray jsonArray = new JSONArray();
                        jsonObject.put(getPingYin(tempObject.getString("name")) + "Children" + i, jsonArray);
                    }
                }
                if (tempObject.containsKey("rows")) {
                    tempObject.replace("rows", jsonObject);
                } else {
                    tempObject.put("rows", jsonObject);
                }
            }
            tempObject.put("tableName", ((HashMap) dynamicTemplate).get("name"));
            tempObject.put("id", id);
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
            String result = gson.toJson(tempObject);
//            String result = JSON.toJSONStringWithDateFormat(tempObject, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue);
            //session.close();
            return result;
        } else {
            //session.close();
            return null;
        }
    }

    @Override
    public String getGpsParentIdByTemplateAndId(String entityName, String id) {
        String gpsParentId = null;
        String hql1 = String.format(" from DynamicTemplate where name='%s'", entityName);
        List<Object> dynamicTableObj = this.dynamicTemplateRepository.createQueryList(hql1);
        String recordGpsLocation = null;
        if(dynamicTableObj != null && dynamicTableObj.size() >= 1){
            HashMap dynamicTable = (HashMap) dynamicTableObj.get(0);
            String type = dynamicTable.get("type").toString();
            if(!type.equals("patrol")){
                return gpsParentId;
            }
            String jsonContent = dynamicTable.get("jsonContent").toString();
            JSONObject jsonObject = JSON.parseObject(jsonContent);
            if (jsonObject != null) {
                JSONArray jsonArrayFieldColumns = (JSONArray) jsonObject.get("fieldColumns");
                if (jsonArrayFieldColumns != null) {
                    for (int k = 0; k < jsonArrayFieldColumns.size(); k++) {
                        String frontType = ((JSONObject) jsonArrayFieldColumns.get(k)).get("frontType").toString().toUpperCase();
                        if ("recordGpsLocation".toUpperCase().equals(frontType)) {
                            recordGpsLocation = ((JSONObject) jsonArrayFieldColumns.get(k)).get("fieldName").toString();
                            break;
                        }
                    }
                }
            }
        }
        if(recordGpsLocation != null){
            String hql = String.format("select %s from %s ", recordGpsLocation, entityName);
            if (id != null && !"".equals(id) && !"null".equals(id) && !"undefined".equals(id)) {
                hql += String.format(" where id='%s'", id);
                List<Object> results = this.dynamicTemplateRepository.createQueryList(hql);  // session.createQuery(hql).list();
                if(results != null && results.size() >= 1){
                    gpsParentId = results.get(0).toString();
                }
            }
        }
        return gpsParentId;
    }

    /**
     * 保存json,hbm.xml到数据库中
     *
     * @param entityName
     * @param dynamicTemplate
     * @return
     */
    public boolean saveDynamic2Database(String entityName, DynamicTemplate dynamicTemplate) {
        try {
            // 将数据结构(json)保存到数据库
            String content = JSON.toJSONString(dynamicTemplate);
            Map dynamicTemplateMap = new HashMap();
            dynamicTemplateMap.put("name", entityName);
            dynamicTemplateMap.put("type", dynamicTemplate.getType());
            dynamicTemplateMap.put("jsonContent", content);
            dynamicTemplateMap.put("updateUser", "");
            dynamicTemplateMap.put("sorting", dynamicTemplate.getSorting());
            dynamicTemplateMap.put("landType", dynamicTemplate.getLandType());

            Object parentId = getPingYin(dynamicTemplate.getName());
//            session.saveOrUpdate("DynamicTemplate", dynamicTemplateMap);
            Set<HashMap<String, Object>> childrenXmlObject = new HashSet<>();
            // 保存主表xml内容到数据库
            String xmlContent = getXmlContentFromFile(entityName);
            if (xmlContent != null && parentId != null) {
                HashMap<String, Object> childMaps = new HashMap<>();
                HashMap<String, Object> dynamicTemplateMapChild = new HashMap();
                dynamicTemplateMapChild.put("id", getPingYin(dynamicTemplate.getName()));
                dynamicTemplateMapChild.put("type", "parent");
                dynamicTemplateMapChild.put("xmlContent", xmlContent);
                dynamicTemplateMapChild.put("xmlFileName", getPingYin(dynamicTemplate.getName()) + ".hbm.xml");
                dynamicTemplateMapChild.put("parentId", parentId);
                //session.saveOrUpdate("DynamicTemplateChild", dynamicTemplateMapChild);
                childrenXmlObject.add(dynamicTemplateMapChild);

                if (dynamicTemplate.getChildrenTable() != null && dynamicTemplate.getChildrenTable().size() > 0) {
                    for (int i = 0; i < dynamicTemplate.getChildrenTable().size(); i++) {
//                        DynamicTemplate childDynamicTemplate = dynamicTemplate.getChildrenTable().get(i);
                        String childrenXmlFile = getPingYin(dynamicTemplate.getName()) + "Children" + i;
                        xmlContent = getXmlContentFromFile(childrenXmlFile);
                        if (xmlContent != null) {
                            HashMap<String, Object> dynamicTemplateMapChild2 = new HashMap();
                            dynamicTemplateMapChild2.put("id", childrenXmlFile);
                            dynamicTemplateMapChild2.put("type", "child");
                            dynamicTemplateMapChild2.put("xmlContent", xmlContent);
                            dynamicTemplateMapChild2.put("xmlFileName", childrenXmlFile + ".hbm.xml");
                            dynamicTemplateMapChild2.put("parentId", parentId);
                            //session.saveOrUpdate("DynamicTemplateChild", dynamicTemplateMapChild2);
                            childrenXmlObject.add(dynamicTemplateMapChild2);
                        }

                    }
                }

            }
//            Session session = this.getSessionFactory().openSession();
//            Transaction tx = session.beginTransaction();
//            dynamicTemplateMap.put("childrenXml", childrenXmlObject);
//            session.saveOrUpdate(DynamicTemplateClassName, dynamicTemplateMap);
//            tx.commit();
//            session.close();
            dynamicTemplateMap.put("childrenXml", childrenXmlObject);
            this.dynamicTemplateRepository.saveOrUpdate(DynamicTemplateClassName, dynamicTemplateMap);

            return true;
        } catch (Exception ex) {
            System.out.print("saveDynamic2Database:" + ex.toString());
            return false;
        }
    }


    /**
     * 生成Hbm文件
     *
     * @param entityName
     * @param dynamicTemplate
     */
    public boolean generateHbm(String entityName, DynamicTemplate dynamicTemplate) {
        try {
            this.saveHbm2File(entityName, dynamicTemplate.getFieldColumns(), dynamicTemplate);
            if (dynamicTemplate.getChildrenTable() != null && dynamicTemplate.getChildrenTable().size() > 0) {
                for (int i = 0; i < dynamicTemplate.getChildrenTable().size(); i++) {
                    List<FieldColumn> fieldColumns = dynamicTemplate.getChildrenTable().get(i).getFieldColumns();
                    if (fieldColumns == null || fieldColumns.size() <= 0) {
                        continue;
                    }
                    String tempEntityName = entityName + "Children" + i;
                    this.saveHbm2File(tempEntityName, fieldColumns, null);
                }
            }
            this.dynamicTemplateRepository.setSessionFactoryNull();  // _sessionFactory = null;       //重新读取resources文件
            return true;
        } catch (Exception ex) {
            System.out.print("generateHbm:" + ex.toString());
            return false;
        }
    }


    /**
     * 获取hbm.Xml
     *
     * @param entityName
     * @return
     */
    private String getXmlContentFromFile(String entityName) {
        File cfgFile = null;
        try {
            cfgFile = ResourceUtils.getFile("classpath:config/mapping/" + entityName + ".hbm.xml");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (cfgFile != null) {
            String hbmPath = cfgFile.getParent() + File.separator;  // "/Users/ziqilv/大地吉信/项目/瓦屋山/source/PatrolService/build/resources/main/config/mapping/";
            String fileName = entityName + ".hbm.xml";

            File file = new File(hbmPath, fileName);
            if (file.exists()) {
                return readFile(file.getPath());
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 保存hbm.xml到文件
     *
     * @param entityName
     * @param fieldColumns
     * @param dynamicTemplate
     * @return
     */
    private boolean saveHbm2File(String entityName, List<FieldColumn> fieldColumns, DynamicTemplate dynamicTemplate) {
        try {
            File cfgFile = ResourceUtils.getFile("classpath:config/mapping/DefaultTemplate.hbm.xml");
            String hbmPath = cfgFile.getParent() + File.separator;  // "/Users/ziqilv/大地吉信/项目/瓦屋山/source/PatrolService/build/resources/main/config/mapping/";
            String fileName = entityName + ".hbm.xml";

            File file = new File(hbmPath, fileName);
            if (file.exists()) {
                file.delete();
            }
            createFile(hbmPath, fileName);
            String xmlContent = "";
            //head information
            xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                    "<!DOCTYPE hibernate-mapping PUBLIC \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n" +
                    "        \"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd\">\n" +
                    "\n" +
                    "<hibernate-mapping>\n" +
                    "    <!-- 此处不需要类名，和包名 -->\n" +
                    "    <class entity-name=\"" + entityName + "\" table=\"" + entityName + "\">\n";

            //body information
            xmlContent += "        <id name=\"id\" type=\"java.lang.String\" length=\"36\" column=\"ID\">\n" +
                    "            <generator class=\"assigned\"/>\n" +
                    "        </id>\n";

            boolean isFindXYLocation = false;
            //循环写入各个属性的信息
            for (int i = 0; i < fieldColumns.size(); i++) {
                FieldColumn fieldColumn = fieldColumns.get(i);
                fieldColumn.setFieldNameDatabse(getPingYin(fieldColumn.getFieldName()));
                String tempColumn = "";
                String fieldType = fieldColumn.getFieldType();
                if (fieldType == null || fieldType == "") {
                    fieldType = fieldColumn.getFrontType();
                }
                switch (fieldType) {
                    case "number":
                    case "int":
                        fieldType = "java.lang.Integer";
                        break;
                    case "simpleLine":
                        fieldType = "java.lang.Long";
                        break;
                    case "double":
                        fieldType = "java.lang.Double";
                        break;
                    case "locationX":
                    case "locationY":
                    case "locationZ":
                    case "locationXNoEdit":
                    case "locationYNoEdit":
                    case "locationZNoEdit":
                        isFindXYLocation = true;
                        fieldType = "java.lang.Double";
                        break;
                    case "date":
                        fieldType = "java.util.Date";
                        break;
                    case "text":
                        fieldType = "text";
                        break;
                    case "boolean":
                        fieldType = "boolean";
                        break;
                    case "startDateTime":
                        tempColumn = "        <property column=\"" + fieldColumn.getFieldNameDatabase() + "\" name=\"开始时间\"  type=\"java.sql.Timestamp\" />\n";
                        xmlContent += tempColumn;
                        break;
                    case "endDateTime":
                        tempColumn = "        <property column=\"" + fieldColumn.getFieldNameDatabase() + "\" name=\"结束时间\"  type=\"java.sql.Timestamp\" />\n";
                        xmlContent += tempColumn;
                        break;
                    case "imageMultiple":
                    case "image": {
                        fieldType = "java.lang.String";
                        if ("image".equals(fieldType) || "imageMultiple".toLowerCase().equals(fieldType) || "image".equals(fieldColumn.getFrontType().toLowerCase()) || "imageMultiple".toLowerCase().equals(fieldColumn.getFrontType().toLowerCase())) {
                            String oneToMany = "        <set name=\"" + fieldColumn.getFieldName() + "PhotoChildren" + "\" cascade=\"all\" lazy=\"false\" inverse=\"false\">  \n" +
                                    "            <key column=\"parent_id\" property-ref=\"" + fieldColumn.getFieldName() + "\"></key>  \n" +
                                    "            <one-to-many class=\"Photo\" not-found=\"ignore\"/>  \n" +
                                    "        </set>  \n";
                            xmlContent += oneToMany;
                        }
                        break;
                    }
                    case "signatureMultiple":
                    case "signature": {
                        fieldType = "java.lang.String";
                        if ("signature".equals(fieldType) || "signatureMultiple".toLowerCase().equals(fieldType) || "signature".equals(fieldColumn.getFrontType().toLowerCase()) || "signatureMultiple".toLowerCase().equals(fieldColumn.getFrontType().toLowerCase())) {
                            String oneToMany = "        <set name=\"" + fieldColumn.getFieldName() + "PhotoChildren" + "\" cascade=\"all\" lazy=\"false\" inverse=\"false\">  \n" +
                                    "            <key column=\"parent_id\" property-ref=\"" + fieldColumn.getFieldName() + "\"></key>  \n" +
                                    "            <one-to-many class=\"Photo\" not-found=\"ignore\"/>  \n" +
                                    "        </set>  \n";
                            xmlContent += oneToMany;
                        }
                        break;
                    }
                    case "recordGpsLocation": {
                        fieldType = "java.lang.String";
                        tempColumn = "        <property column=\"" + fieldColumn.getFieldNameDatabase() + "Length" + "\" name=\"" + fieldColumn.getFieldName() + "Length" + "\"  type=\"java.lang.Double\" />\n";
                        xmlContent += tempColumn;

                        String oneToMany = "        <set name=\"" + fieldColumn.getFieldName() + "GpsLocationChildren" + "\" cascade=\"all\" lazy=\"false\" order-by=\"createDateTime\">  \n" +

                                "            <key column=\"parent_id\" property-ref=\"" + fieldColumn.getFieldName() + "\"></key>  \n" +
                                "            <one-to-many class=\"GpsLocation\" not-found=\"ignore\"/>  \n" +
                                "        </set>  \n";
                        xmlContent += oneToMany;
                    }
                    break;
                    case "audio": {
                        fieldType = "java.lang.String";
                        String oneToMany = "        <set name=\"" + fieldColumn.getFieldName() + "AudioChildren" + "\" cascade=\"all\" lazy=\"false\" inverse=\"false\">  \n" +
                                "            <key column=\"parent_id\" property-ref=\"" + fieldColumn.getFieldName() + "\"></key>  \n" +
                                "            <one-to-many class=\"Audio\" not-found=\"ignore\"/>  \n" +
                                "        </set>  \n";
                        xmlContent += oneToMany;
                    }
                    break;
                    case "geometryPolygon": {
                        isFindXYLocation = false;
                        String tempColumn1 = "        <property name=\"geom\" type=\"com.vividsolutions.jts.geom.Polygon\">\n";
                        if (this.applicationProperties != null && this.applicationProperties.getSrid() != null) {
                            tempColumn1 += "            <column name=\"geom\" sql-type=\"geometry(Polygon," + applicationProperties.getSrid() + ")\" />\n";
                        } else {
                            tempColumn1 += "            <column name=\"geom\" sql-type=\"geometry(Polygon,4326)\" />\n";
                        }
                        tempColumn1 += "        </property>\n";
                        xmlContent += tempColumn1;
                    }
                    break;
                    case "geometryPolyline": {
                        isFindXYLocation = false;
                        String tempColumn1 = "        <property name=\"geom\" type=\"com.vividsolutions.jts.geom.LineString\">\n";
                        if (this.applicationProperties != null && this.applicationProperties.getSrid() != null) {
                            tempColumn1 += "            <column name=\"geom\" sql-type=\"geometry(LineString," + applicationProperties.getSrid() + ")\" />\n";
                        } else {
                            tempColumn1 += "            <column name=\"geom\" sql-type=\"geometry(LineString,4326)\" />\n";
                        }
                        tempColumn1 += "        </property>\n";
                        xmlContent += tempColumn1;
                    }
                    break;
                    default:
                        fieldType = "java.lang.String";
                        break;
                }
                //createDateTime,startDateTime, endDateTime,ID 单独处理
                if (!"createDateTime".toUpperCase().equals(fieldColumn.getFieldName().toUpperCase()) && !"ID".equals(fieldColumn.getFieldName().toUpperCase()) &&
                        !"geometryPolyline".toUpperCase().equals(fieldColumn.getFrontType().toUpperCase()) && !"geometryPolygon".toUpperCase().equals(fieldColumn.getFrontType().toUpperCase()) &&
                        !"开始时间".toUpperCase().equals(fieldColumn.getFieldName().toUpperCase()) && !"结束时间".toUpperCase().equals(fieldColumn.getFieldName().toUpperCase())) {
                    tempColumn = "        <property column=\"" + fieldColumn.getFieldNameDatabase() + "\" name=\"" + fieldColumn.getFieldName() + "\"  type=\"" + fieldType + "\"/>\n";
                    xmlContent += tempColumn;
                }
            }
            // 主表添加创建时间,开始时间,结束时间, 创建人，设备Id
            if (true) {
                String tempColumn = "        <property name=\"createDateTime\" type=\"java.sql.Timestamp\" update=\"false\" generated=\"insert\">\n" +
                        "            <column name=\"createDateTime\" sql-type=\"timestamp\" default=\"CURRENT_TIMESTAMP\"/>\n" +
                        "        </property>\n";
                xmlContent += tempColumn;
                tempColumn = "        <property column=\"createAuthor\" name=\"createAuthor\"  type=\"java.lang.String\" length=\"36\"/>\n";
                xmlContent += tempColumn;

                tempColumn = "        <property column=\"deviceId\" name=\"deviceId\"  type=\"java.lang.String\" length=\"36\"/>\n";
                xmlContent += tempColumn;
//                if (isFindXYLocation == true ||  (dynamicTemplate.getGeometryType()!=null && "".equals(dynamicTemplate.getGeometryType()))) {
                if (isFindXYLocation == true ) {
                    String tempGeometryType="Point";
//                    if (dynamicTemplate.getGeometryType()!=null && !"".equals(dynamicTemplate.getGeometryType())){
//                        tempGeometryType=dynamicTemplate.getGeometryType();
//                    }
                    tempColumn = "        <property name=\"geom\" type=\"com.vividsolutions.jts.geom."+tempGeometryType+"\">\n";
                    if (this.applicationProperties != null && this.applicationProperties.getSrid() != null) {
                        tempColumn += "            <column name=\"geom\" sql-type=\"geometry("+tempGeometryType+"," + applicationProperties.getSrid() + ")\" />\n";
                    } else {
                        tempColumn += "            <column name=\"geom\" sql-type=\"geometry("+tempGeometryType+",4326)\" />\n";
                    }
                    tempColumn += "        </property>\n";
                    xmlContent += tempColumn;
                }
            }
            if (dynamicTemplate != null) {
                if (dynamicTemplate.getChildrenTable() != null && dynamicTemplate.getChildrenTable().size() > 0) {
                    for (int i = 0; i < dynamicTemplate.getChildrenTable().size(); i++) {
                        String childClassName = getPingYin(dynamicTemplate.getChildrenTable().get(i).getName());
                        String oneToMany = "        <set name=\"" + entityName + "Children" + i + "\" cascade=\"all\" lazy=\"false\" inverse=\"false\">  \n" +
                                "            <key column=\"parent_id\"></key>  \n" +
                                "            <one-to-many class=\"" + entityName + "Children" + i + "\" not-found=\"ignore\"/>  \n" +
                                "        </set>  \n";
                        xmlContent += oneToMany;
                        dynamicTemplate.getChildrenTable().get(i).setDescription(entityName + "Children" + i);
                    }
                }
            } else {
                String tempColumn = "        <property column=\"parent_id\" name=\"parentId\" length=\"36\" type=\"java.lang.String\"/>\n";
                xmlContent += tempColumn;
            }
            xmlContent += "    </class>\n" + "</hibernate-mapping>\n";
            //tail information
            writeFile(hbmPath, fileName, xmlContent);
            return true;
        } catch (Exception ex) {
            System.out.print("saveHbm2File:" + ex.toString());
            return false;
        }
    }

    private void savePicture2File(HashMap<String, Object> photoList) {
        if (photoList == null || photoList.size() <= 0) {
            return;
        }
        Object[] keys = photoList.keySet().toArray();
        if (keys == null) {
            return;
        }
        for (int i = 0; i < keys.length; i++) {
            Object object = photoList.get(keys[i]);
            if (object == null) {
                continue;
            }
            String tempPhotoContent = object.toString();
            if (tempPhotoContent != null) {
                String rootPath = request.getRealPath("/") + File.separator + "attached" + File.separator + keys[i] + ".png";
                if (tempPhotoContent.contains(";base64,")) {
                    tempPhotoContent = tempPhotoContent.substring(tempPhotoContent.indexOf(";base64,") + ";base64,".length()); // tempPhotoContent.replace("data:image/jpeg;base64,", "");
                }
                if (tempPhotoContent != "") {
                    ImageHelper.base64StringToImage(tempPhotoContent, rootPath);
                }
            }
        }

    }

    /**
     * 将字符串中的中文转化为拼音,英文字符不变
     *
     * @param inputString 汉字
     * @return
     */
    public static String getPingYin(String inputString) {
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        format.setVCharType(HanyuPinyinVCharType.WITH_V);
        String output = "";
        if (inputString != null && inputString.length() > 0
                && !"null".equals(inputString)) {
            char[] input = inputString.trim().toCharArray();
            try {
                for (int i = 0; i < input.length; i++) {
                    if (java.lang.Character.toString(input[i]).matches(
                            "[\\u4E00-\\u9FA5]+")) {
                        String[] temp = PinyinHelper.toHanyuPinyinStringArray(
                                input[i], format);
                        output += temp[0];
                    } else {
                        output += java.lang.Character.toString(input[i]);
                    }
                }
            } catch (BadHanyuPinyinOutputFormatCombination e) {
                e.printStackTrace();
            }
        } else {
            return "*";
        }
        return output;
    }


    public boolean createFile(String filePath, String fileName) throws IOException {
        boolean result = false;
        File file = new File(filePath, fileName);
        if (file.exists()) {
            if (file.isFile()) {
                result = true;
                System.out.println(fileName + " 文件已存在！");
            } else {
                System.out.println("对不起,该路径为目录！");
            }
        } else {
            file.createNewFile();
            result = true;
            System.out.println("文件创建成功:" + fileName);
        }
        return result;
    }

    public void writeFile(String filePath, String fileName, String content) throws IOException {
        //        FileWriter fw = new FileWriter(filePath + fileName, true);
        //        fw.write(content);
        //        fw.close();

        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(filePath + fileName), "UTF-8");
        out.write(content);
        out.flush();
        out.close();
    }

    /**
     * 读取文件
     *
     * @param filePath
     * @return
     */
    private String readFile(String filePath) {

        String str = "";
        File file = new File(filePath);
        try {
            if (file.exists()) {
                FileInputStream in = new FileInputStream(file);
                // size  为字串的长度 ，这里一次性读完
                int size = in.available();
                byte[] buffer = new byte[size];
                in.read(buffer);
                in.close();
                str = new String(buffer, "utf-8");
            } else {
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return str;
    }

    /**
     * 获取应用程序路径
     *
     * @return
     */
    private String getApplicationPath() {
        String rootPath = request.getSession().getServletContext().getRealPath("/") + File.separator + "attached";
        return rootPath;
    }
}
